新版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;
}
相关推荐
哈茶真的c39 分钟前
【书籍心得】左耳听风:传奇程序员练级攻略
java·c语言·python·go
喝养乐多长不高41 分钟前
JAVA微服务脚手架项目详解(三)
java·大数据·微服务·文件·地图·oss
万邦科技Lafite1 小时前
1688图片搜索商品API接口(item_search_img)使用指南
java·前端·数据库·开放api·电商开放平台
落落落sss1 小时前
java实现排序
java·数据结构·算法
czhc11400756631 小时前
c# 1121 构造方法
java·javascript·c#
Z***25801 小时前
Java爬虫框架
java·开发语言·爬虫
晓华-warm2 小时前
Warm-Flow 1.8.4 票签新增多种通过率策略!
java·中间件·流程图·jar·开源软件·工作流
m***11902 小时前
【SpringBoot】Spring Boot 项目的打包配置
java·spring boot·后端
李慕婉学姐2 小时前
Springboot剪纸数字博物馆系统6wd19a3a(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·spring boot·后端
90后小陈老师2 小时前
用户管理系统 05 实现后端注册功能 | Java新手实战 | 最小架构 | 期末实训 | Java+SpringBoot+Vue3
java·开发语言·spring boot·后端·spring·maven·mybatis