新版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;
}
相关推荐
刘一说2 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
卷福同学9 分钟前
来上海三个月,我在马路边上遇到了阿里前同事...
java·后端
bingbingyihao2 小时前
多数据源 Demo
java·springboot
在努力的前端小白7 小时前
Spring Boot 敏感词过滤组件实现:基于DFA算法的高效敏感词检测与替换
java·数据库·spring boot·文本处理·敏感词过滤·dfa算法·组件开发
一叶飘零_sweeeet9 小时前
从繁琐到优雅:Java Lambda 表达式全解析与实战指南
java·lambda·java8
艾伦~耶格尔10 小时前
【集合框架LinkedList底层添加元素机制】
java·开发语言·学习·面试
一只叫煤球的猫10 小时前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
最初的↘那颗心10 小时前
Flink Stream API 源码走读 - print()
java·大数据·hadoop·flink·实时计算
JH307311 小时前
Maven的三种项目打包方式——pom,jar,war的区别
java·maven·jar
带刺的坐椅12 小时前
轻量级流程编排框架,Solon Flow v3.5.0 发布
java·solon·workflow·flow·solon-flow