新版IDEA提示@Autowired不建议字段注入

随着项目的复杂度的增加,我们通常会在一个业务类中注入其他过多的业务类。从而使当前的业务层扩充成一个大而全的功能模块。那么就容易出现一下问题

  • 字段注入会让依赖关系变得不那么明显,因为你无法通过构造函数看到所有的依赖项。使用构造函数时,所有必需的组件都会在方法签名中列出,使得依赖关系更加清晰。
  • 如果 @Autowired 注解的字段没有注入成功,且后续使用时没有进行空值检查,可能会导致空指针异常(NullPointerException)。构造函数注入可以确保所有必须依赖项在对象构造时被提供,当未能注入时,构造过程将失败并抛出异常。
  • 使用字段注入可能导致循环依赖问题,尤其是在两个或多个 beans 互相依赖时。Spring 容器可以通过 setter 注入来解决循环依赖,但构造函数注入则不可以。
  • 字段注入会隐藏依赖的生命周期管理特性。当需要进行作用域(如单例、原型等)的特定管理时,构造函数注入更直观,且不容易出现意外的作用域问题。

尽管字段注入是一种简单的方法,可以快速快速获得依赖,但它并不是最佳实践。为了确保代码的可维护性、可测试性和清晰性,推荐使用构造函数注入和方法注入。通过这种方式,你可以明确依赖关系,避免潜在的问题,并提升代码的质量和可读性。

使用字段注入

java 复制代码
@Slf4j
@Service
@Transactional
public class StockService {

    @Autowired
    private MaterialService materialService;

    @Autowired
    private StorageLocationService storageLocationService;

    @Autowired
    private StorageStockService storageStockService;

    @Autowired
    private StorageStockMovementsService storageStockMovementsService;

    @Autowired
    private StorageInboundService storageInboundService;

    @Autowired
    private StorageInboundMaterialService storageInboundMaterialService;
}

(StockService 是专门的服务组合,将多个业务服务提取到一个类中,管理它们的交互。避免违反了单一职责原则)

使用构造器(推荐)

java 复制代码
@Slf4j
@Service
@Transactional
public class StockService {

    private final MaterialService materialService;
    private final StorageLocationService storageLocationService;
    private final StorageStockService storageStockService;
    private final StorageStockMovementsService storageStockMovementsService;
    private final StorageInboundService storageInboundService;
    private final StorageInboundMaterialService storageInboundMaterialService;

    public StockService(MaterialService materialService, StorageLocationService storageLocationService, StorageStockService storageStockService, StorageStockMovementsService storageStockMovementsService, StorageInboundService storageInboundService, StorageInboundMaterialService storageInboundMaterialService) {
        this.materialService = materialService;
        this.storageLocationService = storageLocationService;
        this.storageStockService = storageStockService;
        this.storageStockMovementsService = storageStockMovementsService;
        this.storageInboundService = storageInboundService;
        this.storageInboundMaterialService = storageInboundMaterialService;
    }
}

有助于提高类的可测试性。如果项目使用了 Lombok,可以考虑使用 @Autowired 和 @AllArgsConstructor 来减少样板代码。

java 复制代码
@Slf4j
@Service
@Transactional
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class StockService {

    private final MaterialService materialService;
    private final StorageLocationService storageLocationService;
    private final StorageStockService storageStockService;
    private final StorageStockMovementsService storageStockMovementsService;
    private final StorageInboundService storageInboundService;
    private final StorageInboundMaterialService storageInboundMaterialService;
}
相关推荐
辣机小司20 小时前
【软件设计师】自编思维导图和学习资料分享(中级已过)
java·c++·软考·软件设计师
爱笑的眼睛1120 小时前
深入解析Matplotlib Axes API:构建复杂可视化架构的核心
java·人工智能·python·ai
乐观甜甜圈21 小时前
JDK8 中线程实现方法与底层逻辑详解
java
尤物程序猿21 小时前
Java如何不建表完成各种复杂的映射关系(鉴权概念、区域概念、通用概念)
java·开发语言
cike_y21 小时前
JSP内置对象及作用域&双亲委派机制
java·前端·网络安全·jsp·安全开发
也许是_21 小时前
大模型应用技术之 Spring AI 2.0 变更说明
java·人工智能·spring
xunyan623421 小时前
面向对象(下)-内部类的分类
java·学习
青木川崎21 小时前
Mac使用idea连接svn报错svn: E230001: Server SSL certificate verification failed
svn·intellij-idea·ssl
巴拉巴拉~~21 小时前
KMP 算法通用进度条组件:KmpProgressWidget 多维度 + 匹配进度联动 + 平滑动画
java·服务器·前端
Yeniden1 天前
Deepeek用大白话讲解 --> 迭代器模式(企业级场景1,多种遍历方式2,隐藏集合结构3,Java集合框架4)
java·开发语言·迭代器模式