June 22, 2017 Webby

Instant Necessity: Spring’s @Autowired

Occasionally a piece of software introduces a new feature that is so useful that it instantly becomes a must, to the point that you ask yourself how you managed to live without it for so long.

It’s the case of Spring’s @Autowired annotation, introduced in version 2.5.

One of the downsides of Spring has always been the amount of XML configuration required. To provide a trivial example, you typically have a client class that uses a service class

public class MyClient {

  private MyService myService;

  public void setMyService(MyService myService) {
    this.myService = myService;
  }

  // methods that use myService...
}

and then you inject the service implementation in the XML configuration

<bean id="myClient" class="myapp.MyClient">
  <property name="myService" ref="myService"/>
</bean>

Now the problem is that this pattern is repeated over and over again. Any non-trivial application defines at least tens of beans, and each one has a few properties that needs to be injected like this, so the amount of XML required quickly grows.

Since it’s clear from the Java code alone that MyClient requires a MyService implementation, and usually there’s a single MyService implementation defined in the whole Spring context, it would be great if we could tell Spring to automatically inject that myService property without extra XML configuration.

The @Autowired annotation introduced in Spring 2.5 lets you do exactly that. Using @Autowired, the trivial example above becomes even simpler

public class MyClient {

  @Autowired
  private MyService myService;

  // methods that use myService...
}

and

<bean id="myClient" class="myapp.MyClient"/>

Repeat this simplification for tens or hundreds of beans and the advantages become more apparent.

Note that you can have @Autowired on a setter method rather than on the member variable if you prefer; it’s sometimes useful to have a setter method for testing (although I usually prefer having an alternate constructor that takes the required service as an argument).

The only additional requirement is to add the following bean to your context configuration to tell Spring to process @Autowired annotations:

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

See the relevant section in the Spring Reference for more information on the @Autowired annotation.