I am Spring for DI and am NOT using XML.
Based on configuration (eg. an xml/properties file), I am looking to create a number of beans (exact number is determined by the configuration) of a specific type to put in my context so that they can be autowired into classes.
I would autowire by: @Autowired public MyClass(List<MyType> types)
I am looking at using an class annotated with @Configuration
.
So I can do something like this:
@Configuration
public MyConfigurationClass {
@Autowired
public void configure(ApplicationContext context) {
// register stuff here
}
}
...but it doesn't "feel" right...
What is the "Spring" way to achieve this?
EDIT:
Imagine this code, where To
and Ty
are just empty class definitions.
@Configuration
public class Config {
@Bean
public Collection<Ty> tyList() {
return new ArrayList<Ty>() {{
this.add(new Ty()); // could be any number of Ty instances.
}};
}
@Bean
public To to(Collection<Ty> tylist) {
return new To();
}
}
If you don't need to have separate qualifiers and can Autowire as List you can do this in Spring 4:
@Configuration
public MyConfigurationClass {
@Bean
public List<MyType> configure() {
//create your dynamical list here
}
}
But for Spring 3 (where generics were ignored) you would be safer to use:
@Configuration
public MyConfigurationClass {
@Bean
@Qualifier("mylist")
public List<MyType> configure() {
//create your dynamical list here
}
}
and autowire:
@Autowired public MyClass(@Qualifier("mylist") List<MyType> types)
With this you wouldn't need to touch ApplicationContext instance directly. It's not considered as very good practice.
EDIT:
Did you try this?:
@Configuration
public class Config {
@Bean
@Qualifier("tylist")
public Collection<Ty> tyList() {
return new ArrayList<Ty>() {{
this.add(new Ty()); // could be any number of Ty instances.
}};
}
@Bean
public To to(@Qualifier("tylist") Collection<Ty> tylist) {
return new To();
}
}
I think it depends on where and how properties are read. If you read those properties using vanilla java, you could register bean definitions by implementing BeanFactoryPostProcessor. However, if the properties themselves come as a bean (eg. as a result of @ConfigurationProperties), I'm somewhat confident you're out of luck. After googling for some time, I come to conclusion that the only robust solution is to refactor whole design, and instead of providing multiple MyType beans, provide single MyTypeProvider bean, which in turn would have a single method with signature List<MyType> getStuff()
. Then, at the point where you had List<MyType>
injected, inject List<MyTypeProvider>
instead, and merge their results of getStuff
into a single List<MyType>
. Again, I know this is more of a workaround, but this the best I could find so far.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With