新版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;
}
相关推荐
android_xc21 分钟前
Android Studio适配butterknife遇到的坑
android·ide·android studio·butterknife
a5876924 分钟前
消息队列(MQ)初级入门:详解RabbitMQ与Kafka
java·分布式·microsoft·面试·kafka·rabbitmq
千里码aicood35 分钟前
【springboot+vue】党员党建活动管理平台(源码+文档+调试+基础修改+答疑)
java·数据库·spring boot
Chan1639 分钟前
【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
java·spring boot·后端·sql·spring·intellij-idea·echarts
先做个垃圾出来………1 小时前
差分数组(Difference Array)
java·数据结构·算法
云梦谭1 小时前
Cursor 编辑器:面向 AI 编程的新一代 IDE
ide·人工智能·编辑器
BillKu1 小时前
Java核心概念详解:JVM、JRE、JDK、Java SE、Java EE (Jakarta EE)
java·jvm·jdk·java ee·jre·java se·jakarta ee
刘婉晴2 小时前
【Java】NIO 简单介绍
java·nio
渣哥2 小时前
聊聊我和 ArrayList、LinkedList、Vector 的“一地鸡毛”
java
浮游本尊2 小时前
Java学习第20天 - 性能优化与监控
java