为什么 @Autowired 注解在 IDEA 中会有警告提示
status
Published
type
Post
slug
autowired-annotation-in-idea
date
Jul 28, 2021
tags
Java
Spring
summary
在 IDEA 中,使用 @Autowired 注解会出现警告提示。这是由于最佳实践和设计原则导致的。字段注入方式虽然简洁方便,但存在一些问题,会增加应用程序与框架之间的紧耦合。为了消除警告,可以使用 @Resource 注解替换 @Autowired 注解。三种主要的依赖注入方式是:字段注入、构造函数注入和 Setter 方法注入。推荐使用构造函数注入,并可结合 lombok 来简化代码。
项目使用了 Spring 框架,其中的依赖注入较多使用了
@Autowired
来实现。然而 IDEA 总是会出现如下警告,那么为什么会有这样的提示呢?这个警告是由一些最佳实践和设计原则引起的,原因是字段注入是通过直接将依赖项注入到类的字段中实现的。虽然它在简化代码编写和阅读方面提供了一些便利,但也存在一些问题,
为了不产生警告,我们可以直接用
@Resource
注解来替换 @Autowired
。Spring 框架提供了@Autowired 注解,而 @Resource 注解由 JSR-250 提供,是一个Java标准。使用 @Autowired 注解会产生警告,而使用 @Resource 注解不会,因为 @Autowired 注解导致应用程序与框架之间存在紧耦合,当然在项目中一般不会出现轻易变更 IoC 框架的情况,故这里替换与否都不会有什么问题。
下面是三种主要的依赖注入方式和各自的优缺点。
字段注入:
@Autowired private Dependency dependency;
优点:
- 简洁方便,字段注入方式可以将依赖注入的代码写在字段上方,避免了冗长的构造函数或者setter方法。进而可以直接在类中使用依赖,减少了手动获取依赖的麻烦。
缺点:
- 难以进行单元测试:字段注入方式使得在进行单元测试时,难以通过构造函数或setter方法手动传入依赖的模拟对象。
- 不利于解耦:字段注入将依赖直接暴露在类的外部,增加了类之间的耦合度,不利于后续的维护和扩展。
构造函数注入:
private Dependency dependency; @Autowired public MyClass(Dependency dependency) { this.dependency = dependency; }
优点:
- 显式依赖:通过构造函数注入,明确了类所依赖的对象,提高了代码的可读性和可维护性。
- 可选性注入:构造函数注入可以使用
@Autowired(required = false)
来标记非必须的依赖,使得依赖项成为可选项。
缺点:
- 如果类的依赖较多,构造函数可能变得冗长而复杂。
- 构造函数注入要求依赖项在构造函数中按正确的顺序传递,否则可能导致错误。
Setter方法注入:
private Dependency dependency; @Autowired public void setDependency(Dependency dependency) { this.dependency = dependency; }
优点:
- 灵活性:Setter方法注入可以动态地设置依赖,可以在运行时更改依赖关系,可以在类构造后,重新注入依赖。
- 可以选择性注入:和构造函数注入类似,Setter方法注入也可以使用
@Autowired(required = false)
来标记非必须的依赖。
缺点:
- 破坏封装性:Setter方法注入将依赖项暴露在类的外部,增加了类之间的耦合度。
- 方法调用顺序:在使用Setter方法注入时,需要保证依赖项在调用其他方法之前被正确设置,否则可能导致空指针异常或其他错误。
综合来看,更为推荐的是构造器注入方式,为了解决构造器注入代码的臃肿,可以结合
lombok
来实现。- 引入 lombok 依赖
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency>
- 使用
@RequiredArgsConstructor
注解和final
关键字
@RequiredArgsConstructor @RestController public class DemoController { private final Dependency dependency; }