Spring injects dependencies in constructor without @Autowired annotation

SpringSpring BootDependency InjectionAutowired

Spring Problem Overview


I'm experimenting with examples from this official Spring tutorials and there is a dependency on this code:
https://github.com/spring-guides/gs-async-method/tree/master/complete

If you look at the code on AppRunner.java class, I have 2 questions:

  1. When server is starting, if I put a breakpoint in this class's constructor, seems like in the constructor, the GitHubLookupService is provided by spring, using the @Service bean that was configured. BUT, there was no @Autowired annotation on the constructor, so how in the world this constructor get called with the right dependency? It was supposed to be null.

Is it an automatic assumption of Spring Boot?
Does Spring see "private field + constructor argument, and it assumes it should look for an appropriate bean?
Is it Spring Framework or Spring boot?
Am I missing something?

  1. As I remember, it was mendatory to provide default constructor to beans / service etc. How come this class (AppRunner) doesn't have a default constructor? How does Spring knows that it should run the constructor with the argument? Is it because it is the only constructor?

Spring Solutions


Solution 1 - Spring

Starting with Spring 4.3, if a class, which is configured as a Spring bean, has only one constructor, the @Autowired annotation can be omitted and Spring will use that constructor and inject all necessary dependencies.

Regarding the default constructor: You either need the default constructor, a constructor with the @Autowired annotation when you have multiple constructors, or only one constructor in your class with or without the @Autowired annotation.

Read the @Autowired chapter from the official Spring documentation for more information.

Solution 2 - Spring

Think of it this way... Suppose you have the following component:

@Component 
public class FooService {
    public FooService(Bar bar) { /*whatever*/ }
}

When Spring is scanning this class, it wants to know how it should go about constructing an instance. It's using reflection so it can get a list of all of the constructors at runtime.

In this case, it is completely unambiguous how Spring must construct this instance. There's only one constructor so there is no decision to be made, and no ambiguity at all.

If you add @Autowired here, you are not narrowing anything down, and you are not giving Spring any extra information to help make its decision - its decision is already made because there is only one candidate.

And so, as a convenience, the Spring team decided @Autowired should be optional. Since its not helping the Spring framework to make a decision, its presence is just noise.

If your component has multiple constructors then you can use @Autowired on one of them to tell Spring "use this one, not that one".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwinterView Question on Stackoverflow
Solution 1 - SpringdunniView Answer on Stackoverflow
Solution 2 - SpringMichaelView Answer on Stackoverflow