Reputation: 1342
I am trying create a @Configuration factory bean that should create other (prototype) beans depending on a runtime parameter. I want to use spring java-based configuration but somehow I could not make it work.
Here is an example:
enum PetType{CAT,DOG;}
abstract class Pet {
}
@Component
@Scope("prototype")
class Cat extends Pet{
}
@Component
@Scope("prototype")
class dog extends Pet{
}
@Configuration
public class PetFactory{
@Bean
@Scope("prototype")
public Pet pet(PetType type){
if(type == CAT){
return new Cat();
}else
return new Dog();
}
}
petFactory.animal(PetType.CAT);
I checked spring docs and all related questions asked here but I end up in the case of supplying runtime parameters to the created bean. And I need to supply runtime parameters to the factory that must use them to create different beans.
EDIT: Seems (currently) there is no way to define a parameter to a @Bean annotated method as "runtime". Spring assumes method parameters will be used as constructor args for the new bean and so it tries to satisfy this dependency with container-managed beans.
Upvotes: 5
Views: 3160
Reputation: 164
You can just @Autowire your PetFactory bean into required bean and call animal() method with required type in runtime, like in the following approach:
@Configuration
public class AppConfiguration {
@Bean
@Scope("prototype")
public Pet getPet(PetType type) {
if(type == CAT){
return new Cat();
} else
return new Dog();
}
}
//...
// Then in required class
@Service
public class PetService {
@Autowired
private AppConfiguration configuration;
//.....
public Pet getPetByType(PetType type) {
return configuration.getPet(type);
}
}
Upvotes: 1
Reputation: 4663
Try using @Configurable:
class Factory {
Pet newPetOfType(PetType type) {
switch (type) {
case CAT: return new Cat();
...
}
}
@Configurable
private static class Cat extends Pet {
@Autowired private Prop prop;
...
}
}
Upvotes: 1
Reputation: 9488
This seems like it could be a good use of the Spring Profiles feature. Here you can read about Java configurations, and here about XML Profiles.
Your profile would define a Pet bean. Your factory could then wire that bean in.
To modify which profile you use, simply add: -Dspring.profiles.active=dog or -Dspring.profiles.active=cat (or whatever you name them).
Upvotes: 3