新版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;
}
相关推荐
计算机学姐几秒前
基于SpringBoot+Vue的篮球馆会员信息管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis
kakwooi1 分钟前
JavaEE---Spring IOC(2)
java·spring·java-ee
程序员大金12 分钟前
基于SpringBoot+Vue+MySQL的智能物流管理系统
java·javascript·vue.js·spring boot·后端·mysql·mybatis
茜茜西西CeCe28 分钟前
移动技术开发:登录注册界面
java·gitee·gradle·android studio·安卓·移动技术开发·原生安卓开发
linux_lzj_cainiao29 分钟前
准备招银社招记录
java
不是编程家33 分钟前
C++ 第三讲:内存管理
java·开发语言·c++
尸僵打怪兽34 分钟前
软考(中级-软件设计师)(0919)
java·c语言·数据库·计算机网络·软考·多媒体·软件设计师
Liii4031 小时前
【ARM】Cache深度解读
java·arm开发·spring
litGrey1 小时前
Maven国内镜像(四种)
java·数据库·maven
丶白泽2 小时前
重修设计模式-结构型-桥接模式
java·设计模式·桥接模式