Why Field injection is not recommended using @AutoWired BY AZURE99 · 2020-05-04

A long time ago, while developing with IDEA, I noticed a warning that appeared when using Spring’s dependency injection annotation @autowired on a field

Field injection is not recommended

This prompt does not appear with @resource

Most of the articles on the Internet are about the difference between the two, without mentioning why. At that time, I thought for a long time and came up with the possible reason. However, AFTER so long, I forgot it a little

Constructor injection: uses the constructor’s arguments to inject a dependent Setter injection: uses the method calling the Setter to inject a dependent field injection: So using @Autowired/Resource annotations on fields @Autowired VS @Resource actually, their basic functionality is dependency injection via annotations, but @Autowired is defined by Spring, And @resource is defined by JSR-250. The general function is basically the same, but some details are different:

@qualifier specifies Name. @qualifier specifies ByName. @resource specifies ByName. @autoWired can be used with constructors, methods, parameters, and fields. @resource can only be used with methods and fields providers: The advantages and disadvantages of the various DI modes provided by JSR-250 Refer to the Spring official documentation to recommend the following usage scenarios:

Constructor injection: strong dependency (that is, must use this dependency), immutable (dependencies don’t change very often) Setter injection: Optional (works without this dependency), mutable (dependencies change frequently) Field injection: For the most part, use Field injection as little as possible. If you do use it, @Resource has less coupling to the IoC container than @AutoWired. The disadvantage of Field injection is that you can’t inject immutable object dependencies like constructors do, so constructors and setters are visible to the outside world, But can’t see private fields, natural cannot understand needed to rely on will cause the component and the IoC container tightly coupled (this is the most important reason, left the IoC container to use components, will be very difficult when dependent) lead to the unit test must also use the IoC container, for rely on too much is not obvious, such as I need 10 rely on, If constructor injection is bulky, it’s time to consider whether this component violates the single responsibility principle. Why IDEA is only injected into the @AutoWired warning Field has a number of drawbacks, but it has a major advantage: it’s too convenient. Using constructor or setter injection requires more business-neutral and cumbersome code, which field injection greatly simplifies. And most of the time the business code and the framework are strongly bound, so completely loose coupling is an ideal thing to do, sacrificing agility for too much loose coupling is counterproductive.

So why is IDEA only warning @autowired and ignoring @Resource?

In my opinion, as we mentioned earlier: @AutoWired is provided by Spring, it is a specific annotation provided by a specific IoC, which leads to a strong binding of the application to the framework, which cannot support injection once you switch to another IoC framework. The @Resource is provided by JSR-250, which is the Java standard, and the IoC container we use should be compatible with it so that it will work even if we change containers.