@Autowired
annotations I believe that every Spring developer is familiar with it! In DD's Spring Boot basic tutorial and Spring Cloud basic tutorial also often appear.
But when we use IDEA to write code, we often find that @Autowired
comment. We hover the mouse on it, and we can see this warning message as shown in the figure below:
So why does IDEA give a warning like Field injection is not recommended
With this kind of question below, let's take a comprehensive understanding of the three injection methods in Spring and the advantages and disadvantages between them in various aspects.
Three ways of dependency injection in Spring
Field Injection
One of the major usage scenarios of @Autowired
Field Injection
.
The specific form is as follows:
@Controller
public class UserController {
@Autowired
private UserService userService;
}
This injection method is implemented through Java's reflection mechanism, so private members can also be injected into specific objects.
Constructor Injection
Constructor Injection
is the constructor injection, which is the most recommended way of use 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;
}
}
This injection method is very straightforward. The relationship is established when the object is constructed. Therefore, this method will have requirements on the order of object creation. Of course, Spring will fix this order for you, unless you have a circular dependency, and then it will throw abnormal.
Setter Injection
Setter Injection
will be used @Autowired
notes, but use the Field Injection
different, Field Injection
is used in the member variable, and Setter Injection
when it is used in the Setter function member variable.
The specific form is as follows:
@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
}
This injection method is also well understood, that is, inject the dependent object you want to use by calling the set method of the member variable.
Comparison of three kinds of dependency injection
After knowing the three dependency injection methods provided by Spring, we continue to return to the question mentioned at the beginning of this article: Why does IDEA not recommend the use of Field Injection
?
We can compare the pros and cons between them from the perspective of multiple development tests:
Reliability
From the object construction process and use process, to see whether the use of the object at each stage is reliable to judge:
Field Injection
: unreliableConstructor Injection
: ReliableSetter Injection
: unreliable
Since the constructor has a strict construction order and immutability, it can be used once it is constructed and will not be changed.
Maintainability
Mainly judge from the perspective of easier reading and analysis of dependencies:
Field Injection
: PoorConstructor Injection
: GoodSetter Injection
: Poor
It is also because the key of the dependency is clear that the dependency relationship can be analyzed from the constructor, which is more friendly to how we understand the relationship and maintain the relationship.
When in the case of complex dependencies, check whether the program is easier to write unit tests to judge
Field Injection
: PoorConstructor Injection
: GoodSetter Injection
: Good
Constructor Injection
and Setter Injection
are easier to mock and inject objects, so it is easier to implement unit testing.
Flexibility
Mainly judged based on the coding flexibility during development and implementation:
Field Injection
: Very flexibleConstructor Injection
: Not flexibleSetter Injection
: Very flexible
Since Constructor Injection
has strict order requirements for the design of Bean dependencies, this injection method is not very flexible. On the contrary, Field Injection
and Setter Injection
are very flexible, but they are also a double-edged sword because they bring chaos to the situation.
cyclic relationship detection
The ability to detect whether there is a circular dependency between Beans:
Field Injection
: No detectionConstructor Injection
: automatic detectionSetter Injection
: No detection
performance
Different injection methods, impact on performance
Field Injection
: Start fastConstructor Injection
: Slow startupSetter Injection
: Start fast
The main impact is the startup time. Because Constructor Injection
has strict sequence requirements, it will lengthen the startup time.
Therefore, based on the comparison of the above aspects, the following table can be obtained:
The result is clear at a glance, Constructor Injection
is superior to the other two methods in many aspects, so Constructor Injection
is usually the first choice!
The Setter Injection
than Field Injection
, most are the same, but because of better testability, so when you use @Autowired
when recommended Setter Injection
way, so that IDEA will not be given a warning. At the same time, it also reflects the important position of testability!
Summarize
Finally, for today’s discussion, we give two conclusions for everyone to remember:
- For the use of dependency injection,
Constructor Injection
is the first choice. - When using the
@Autowired
annotation, use theSetter Injection
method, so that the code is easier to write unit tests.
Well, that's all for today's study! If you encounter difficulties in the learning process? You can join our super high-quality Spring technical exchange group , participate in exchanges and discussions, and better study and progress!
original is not easy, welcome to share the content of this article, your support is my motivation for persistence!
Welcome to pay attention to my public account: Program Ape DD, share knowledge and thoughts that can’t be seen elsewhere
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。