Spring @Autowire on Properties vs Constructor

GSUgambit picture GSUgambit · Nov 15, 2016 · Viewed 76.3k times · Source

So since I've been using Spring, if I were to write a service that had dependencies I would do the following:

@Component
public class SomeService {
     @Autowired private SomeOtherService someOtherService;
}

I have now run across code that uses another convention to achieve the same goal

@Component
public class SomeService {
    private final SomeOtherService someOtherService;

    @Autowired
    public SomeService(SomeOtherService someOtherService){
        this.someOtherService = someOtherService;
    }
}

Both of these methods will work, I understand that. But is there some advantage to using option B? To me, it creates more code in the class and unit test. (Having to write constructor and not being able to use @InjectMocks)

Is there something I'm missing? Is there anything else the autowired constructor does besides add code to the unit tests? Is this a more preferred way to do dependency injection?

Answer

JB Nizet picture JB Nizet · Nov 15, 2016

Yes, option B (which is called constructor injection) is actually recommended over field injection, and has several advantages:

  • the dependencies are clearly identified. There is no way to forget one when testing, or instantiating the object in any other circumstance (like creating the bean instance explicitly in a config class)
  • the dependencies can be final, which helps with robustness and thread-safety
  • you don't need reflection to set the dependencies. InjectMocks is still usable, but not necessary. You can just create mocks by yourself and inject them by simply calling the constructor

See this blog post for a more detailed article, by one of the Spring contributors, Olivier Gierke.