28

I have a bean B which I have to create myself (using new B()) and which has @Autowire and @PostConstruct annotations.

How do I make Spring process these annotations from my bean A?

Related question:

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820

2 Answers2

48

Aaron, I believe that your code is correct but I used the following:

B bean = new B();
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean( bean );
factory.initializeBean( bean, "bean" );

The first method will process @Autowire fields and methods (but not classic properties). The second method will invoke post processing (@PostConstruct and any defined BeanPostProcessors).

Application context can be obtained in a bean if it implements ApplicationContextAware interface.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • Maybe my code is wrong. `processInjection()` will only fill `@Autowired` fields while your code should process `@PostConstruct`, too (at least according to the JavaDoc). :-/ – Aaron Digulla Aug 15 '12 at 07:57
  • 3
    Does it also create a dynamic proxy, if the class has been annotated with `@Transactional` annotation for example? – jeromerg Nov 12 '16 at 14:02
  • @jeromerg No. Since the bean was created with `new`, there is no way for Spring to replace the instance with a proxy. The solution here is to move all the `@Transactional` methods into a helper bean which you inject into `B`. – Aaron Digulla Jan 01 '21 at 10:53
  • This method still works as of 11-March-2021. Saved my day even after 9 years of OP. – Parth Manaktala Mar 11 '21 at 11:37
  • 1
    I think the missing piece is that `initializeBean()` returns the proxied version, so the last line should be: `bean = factory.initializeBean( bean, "bean" );` – Luke Mar 16 '21 at 15:35
2

Another option is to let the spring container create automatically a new bean (instead of creating a new instance yourself with the new keyword). Inside a class that needs to instantiate a new been programmatically, inject an instance of AutowireCapableBeanFactory :

@Autowired
private AutowireCapableBeanFactory beanFactory;

Then:

B yourBean = beanFactory.createBean(B.class);

The container will inject instances annotated with @Autowired annotations as usual.

Domenico
  • 1,331
  • 18
  • 22