Exploring Spring's Autowired annotation

June 23, 2009

When writing Spring-enabled JUnit tests, I often make use of the @Autowired annotation to inject my test with various beans from my test context. After much tinkering around with various test configurations, I noticed that the placement of the @Autowired annotation affects the behavior of the injection, which piqued my curiosity.

With a private field and its corresponding setter method annotated with @Autowired, I observed the expected behavior: the setter is called during initialization of the Spring context, and the dependency injected as usual.

I noticed that when I have an @Autowired-annotated private field, it is injected with its appropriate bean with or without a corresponding setter method. Even more perplexing was that the setter is never called when I provided it. How is this field being injected?

With my Eclipse debugger in hand, I took a dive into Spring's source code to investigate. Right off the bat I noticed the AutowiredAnnotationBeanPostProcessor class, which seems to do much of the heavy lifting of processing annotated beans. More specifically, it implements an inner class: AutowiredFieldElement. This class acts as a helper, called by AutowiredAnnotationBeanPostProcessor's postProcessAfterInstantiation() method to perform the field injection that I have until now overlooked.

This method traces back to the InstantiationAwareBeanPostProcessor, the Javadoc of which speaks directly of the intended use for field injection.

Drilling down into the AutowiredFieldElement class, I found that injection of private fields without setter methods is actually a relatively simple excercise of the Java Reflection API. Specifically, through a combination of Field.setAccessible() and Field.set(), the private field is injected with the corresponding bean.