Intellij IDEA 如何去掉 @Autowired 注入警告

本贴最后更新于 1458 天前,其中的信息可能已经时移俗易

现状

在 Service 层注入 Mybatis 的 Mapper 我们通常会使用 @Autowired 自动注入

@Autowired
private ProductMapper productMapper;

但是这样 Intellij IDEA 会显示红色告警,提示不能自动注入。
image.png

当我们在 Controller 层注入 Service 时我们也经常直接在 Filed 上使用 @Autowired 注解,这时候不显示红色警告,但是也显示 Field injection is not recommended 的建议
image.png

原因

第一种情况是因为 IDEA 可以识别并理解 Spring 的上下文。然而 Mapper 接口是 Mybatis 的,IDEA 理解不了。
所以会出现红色告警。

而第二种原因是因为官方不推荐使用 Filed 进行注解,而推荐使用构造器或 Setter 方法进行注解,像下面两种写法就不会出现警告。

private final ProductService productService;
@Autowired
public ProductController(ProductService productService) {
	this.productService = productService;
}

or

private ProductService productService;
@Autowired
public void setProductService(ProductService productService) {
	this.productService = productService;
}

问题是什么

Field 注入看起来非常好,够简洁,代码通俗易懂。你的类可以专注于业务而不被依赖注入所污染。你只需要把 @Autowired 扔到变量之上就好了,不需要特殊的构造器或者 set 方法,依赖注入容器会提供你所需的依赖。
但是 Field 注入会带来 2 个问题:

  • 当注入的对象依赖其他对象,而被依赖的对象没被创建的话就会出现空指针异常。
  • 这样的类没办法在容器之外被重用,也不能期望反射提供其所需的依赖。

详细原因大家可以去这篇文章查看:http://olivergierke.de/2013/11/why-field-injection-is-evil/

构造器注入 VS Setter 注入

Setter 应该被用来注入可变的依赖。当没有提供依赖时,这个类也应该能够运转。当实例化对象后,这些依赖也能随时改变。其实也视情况而变,有时,一个不变的对象是理想状态。有时,最好是能在运行期间改变对象的属性。

构造器注入对象需要依赖的对象初始化后才能正常运转,通过构造器提供这些依赖就能保证对象初始化后就能被使用。使用构造器注入的一个可能的影响就是循环依赖。

怎么解决

我们可以使用 Lombok 提供的注解 @RequiredArgsConstructor 来解决这两个问题(Lombok 这个大家项目都会使用吧)

@Service
@Log4j2
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ProductServiceImpl implements ProductService {
    private final ProductMapper productMapper;
	...
}

这里必须使用 final 修饰符来修饰注入的 Service 或 Mapper
首先我们看看编译后的类是什么样
image.png

编译完成后变成了使用构造器进行注入

认识 @RequiredArgsConstructor

Lombok 官方给出的解释是:
Generates constructor that takes one argument per final / non-null field.
所以它会为 final 和 nonnull 的属性作为参数产生一个构造函数。

而上面我们讲了 Spring 推荐使用 Setter 或构造器注入,那么 @RequiredArgsConstructor 刚好可以完成这件事,而且还简化了你的代码,何乐而不为是不是?

  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3165 引用 • 8206 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • adlered 1

    我记得之前出现过这个问题,给注入的类一个 @Service 注解就好了吧