How can I create a collection of beans that will be properly managed by Spring using a class with a @Configuration annotation.
I would like to do something like this:
@Configuration public Config { @Autowired private SomeConfiguration config; @Bean public List<MyBean> myBeans() { List<MyBean> beans = new ArrayList<MyBean>(); for (Device device : config.getDevices()) { beans.add(new MyBean(device)); } return beans; } }
But the MyBean instances aren't post processed. So their @Autowired methods are not called, the beans are not registered as mbeans and etc. The list is however accessible so that I can autowire a List of MyBean objects.
I cannot use something like:
@Configuration public Config { @Autowired private SomeConfiguration config; @Bean public MyBean myBean1() { ... } @Bean public MyBean myBean2() { ... } }
Since the number of MyBean instances are not known before runtime. The reason I want to do this is because we are controlling a physical machine that have a variable amount of components. And I want to have one bean per component.
I'm currently achieving our goal by using a BeanFactoryPostProcessor like this:
@Component public class MyBeansFactoryPostProcessor implements BeanFactoryPostProcessor { @Autowired private SomeConfiguration config; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeanException { for (Device device : config.getDevices()) { createAndRegister(BeanDefinitionRegistry) beanFactory, device); } } private void createAndRegister(BeanDefinitionRegistry registry, Device device) { register.registerBeanDefinition("device" + device.getId(), BeanDefinitionBuilder.genericBeanDefinition(MyBean.class).addConstructorArgValue(device).getBeanDefinition()); } }
But this just feels like a really ugly hack.
It is a method-level annotation. During Java configuration ( @Configuration ), the method is executed and its return value is registered as a bean within a BeanFactory .
Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context.
If you use @Configuration, all methods marked as @Bean will be wrapped into a CGLIB wrapper which works as if it's the first call of this method, then the original method's body will be executed and the resulting object will be registered in the spring context.
In order to inject your MyBean list try @Resource instead of @Autowired. for e.g.
@Resource public List<MyBean> myBeans
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