为什么Spring推荐使用构造器注入而不是Field注入

前言

我们都知道在 Spring Bean 的注入方式一般分为三种:1、构造器注入 2、Setter注入 3、基于注解的 @Autowired 自动装配(Field 注入)

在以往的项目开发过程中,我们大多会使用方便灵活的 @Autowired 自动装配的方式来管理依赖,但是 Spring 官方却不推荐这么做

Inspection info: Spring Team recommends: “Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies”.

从上述信息中我们可以得知,Spring 团队建议我们使用构造注入的方式管理我们的依赖,对强制依赖使用断言,那么为什么不建议使用自动装配呢

对比构造注入和Field注入

我么可以先来对比 Field 注入和 构造器注入的区别

Field 注入

// Field注入
public class AClass(){
    
    @Autowired
    private BClass bClass;
}
优点
  • 代码少,简洁明了
  • 新增依赖十分方便,不需要修改原有代码
  • 注入简单,只需要使用 @Autowired 注解或者 @Resource 注解
缺点
  • 容易出现空指针异常,Field 注入允许构建对象实例的时候依赖的示例对象为空,这就导致了空指针异常无法尽早的暴露出来
  • 对单元测试不友好,如果使用 Field 注入,那么进行单元测试就需要初始化整个Spring 环境,将所有 Bean 实例化
  • 会出现循环依赖的隐患
  • 容易破坏单一职责原则

构造器注入

// 构造器注入
public class AClass(){
    // 用 final 修饰,遵从依赖不可变原则
    private final BClass bClass;
    
   	public AClass(BClass bClass){
        this.bClass = bClass;
    }
}
优点
  • 解决了依赖循环的问题,如果使用构造器注入,在spring项目启动的时候,就会抛出:BeanCurrentlyInCreationException 从而提醒你避免循环依赖,如果是field注入的话,启动的时候不会报错
  • 强依赖处理,在编译阶段就能暴露出问题
  • 方便单元测试
  • 可以明确的指出依赖关系
缺点
  • 代码冗余,阅读不友好

使用 Lombok 解决构造器注入代码冗余问题

针对构造器注入导致代码过于繁重的问题,我们可以通过 lombok 插件来解决这个问题,使用lombok 的 @RequiredArgsConstructor注解生成一个包含所有常量的构造器

@RequiredArgsConstructor为每个需要特殊处理的字段生成一个带有1个参数的构造函数。所有未初始化的final字段都将获得一个参数,以及任何标记为@NonNull且未在声明位置初始化的字段。对于那些用@NonNull标记的字段,还将生成显式null检查。如果用于标记为@NonNull的字段的任何参数包含null,则构造函数将抛出NullPointerException。参数的顺序与字段在类中出现的顺序相匹配

@Service
@RequiredArgsConstructor
public class LogServiceImpl implements LogService {

    private final LogRepository logRepository;
    private final LogErrorMapper logErrorMapper;
}

// 实际效果等同于

@Service
public class LogServiceImpl implements LogService {

    private final LogRepository logRepository;
    private final LogErrorMapper logErrorMapper;
    
    public LogServiceImpl(final LogRepository logRepository, final LogErrorMapper logErrorMapper) {
        this.logRepository = logRepository;
        this.logErrorMapper = logErrorMapper;
    }
}


  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值