I believe every Spring developer is familiar with it! It also appears frequently in DD’s Spring Boot basics tutorial and Spring Cloud basics tutorial.

However, when we use IDEA to write code, we often find that the @AutoWired annotation has a little yellow line under it. If we hover the mouse over it, we can see the warning message as shown in the picture below:

3. Field injection is not recommended

With that in mind, let’s take a comprehensive look at the three injection methods in Spring and the pros and cons of each of them.

Three dependency injection approaches in Spring

Field Injection

One use case for the @autowired annotation is Field Injection.

The specific form is as follows:

@Controller
public class UserController {

    @Autowired
    private UserService userService;

}
Copy the code

This injection is implemented through Java’s reflection mechanism, so private members can also be injected into concrete objects.

Constructor Injection

Constructor Injection is the most recommended use of Constructor Injection in our daily life.

The specific form is as follows:

@Controller
public class UserController {

    private final UserService userService;

    public UserController(UserService userService){
        this.userService = userService; }}Copy the code

This method of injection is straightforward, and the relationship is established as the object is built, so there are requirements for the order in which the object is created. Spring will take care of that order for you, of course, unless you have a loop dependency, which then throws an exception.

Setter Injection

Setter Injection also uses @autowired, but uses Field Injection in a different way. Field Injection is used on member variables. Is used on Setter functions of member variables.

The specific form is as follows:

@Controller
public class UserController {

    private UserService userService;

    @Autowired
    public void setUserService(UserService userService){
        this.userService = userService; }}Copy the code

The method of injection is also well understood by calling the set method of a member variable to inject the desired dependent object.

A comparison of three dependency injection types

Now that we know about the three dependency Injection methods provided by Spring, we return to the question at the beginning of this article: Why is Field Injection not recommended for IDEA?

We can compare them from the perspective of multiple development tests:

reliability

Judging the reliability of the use of objects in each stage from the process of object construction and use:

  • Field Injection: don’t reliable
  • Constructor InjectionReliable:
  • Setter Injection: don’t reliable

Because constructors have a strict build order and immutability, they are available once built and cannot be changed.

maintainability

Mainly from the perspective of easier to read, analysis of dependencies:

  • Field InjectionPoor:
  • Constructor InjectionGood:
  • Setter InjectionPoor:

Again, because the dependency key is clear, parsing dependencies from constructors is more friendly to how we read and maintain relationships.

testability

See if the program is easier to write unit tests to judge when dealing with complex dependencies

  • Field InjectionPoor:
  • Constructor InjectionGood:
  • Setter InjectionGood:

The Constructor Injection and Setter Injection approaches make it easier to Mock and inject objects, so unit testing is easier to implement.

flexibility

Mainly according to the coding flexibility of the development implementation:

  • Field Injection: very flexible
  • Constructor InjectionFlexible: no
  • Setter Injection: very flexible

Because Constructor Injection has strict ordering requirements for the design of Bean dependencies, this Injection approach is not flexible. On the contrary, Field Injection and Setter Injection are very flexible, but they also bring chaos to the situation, which is also a double-edged sword.

Detection of cyclic relationships

Ability to detect whether there are cyclic dependencies between beans:

  • Field Injection: don’t test
  • Constructor Injection: Automatic detection
  • Setter Injection: don’t test

performance

Impact of different injection modes on performance

  • Field Injection: starting fast
  • Constructor Injection: slow start
  • Setter Injection: starting fast

The main effect is startup time, which may be extended due to the strict ordering of Constructor Injection.

Therefore, based on the above comparison, the following table can be obtained:

The result is clear: Constructor Injection is superior to the other two methods in many ways, so Constructor Injection is usually preferred!

Setter Injection is almost the same as Field Injection, but because it is more tetestable, it is recommended to use Setter Injection when you want to use @autowired. In this way, IDEA will not give a warning. At the same time, it also reflects the importance of testability.

conclusion

Finally, for today’s discussion, we draw two conclusions for your convenience:

  1. In the use of dependency injection,Constructor InjectionIs preferred.
  2. use@AutowiredWhen annotating, useSetter InjectionThat makes it easier to write unit tests.

Well, that’s all for today’s learning! If you have any difficulty in learning? You can join our super high quality Spring technology exchange group, participate in the exchange and discussion, better learning and progress!

Original is not easy, welcome to forward to share this content, your support is my motivation!

Welcome to pay attention to my public account: program ape DD, share the outside can not see the dry goods and thinking!