为啥不推荐使用@Autowired注解做属性注入?

引言

​ 我们平时做项目开发的时候,都比较喜欢使用@Autowired注解来注入依赖,但是大家有没有留意到一个告警:Field injection is not recommended

image-20240215184425175

@Autowired注解注入弊端

​ 该注解注入本质上是通过反射的方式注入,但是属性注入有以下弊端:

1.容易引发空指针异常

​ Java 在初始化一个类时,是按照静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 -> @Autowired 的顺序。所以在执行这个类的构造方法时,user对象尚未被注入,它的值还是 null,这可能导致运行时的空指针异常。对于必须存在的依赖,建议采用@NonNull结合@Autowired,或者直接使用构造器注入,这样在初始化阶段就能发现问题,而不是在运行时。

@Autowired
private User user;

private String company;

public UserDaoImpl(){
    this.company = user.getCompany();
}

编译过程不会报错,但是运行之后报NullPointerException

Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [...]: Constructor threw exception; nested exception is java.lang.NullPointerException

2.初始化顺序不确定性

​ Spring容器对Bean的初始化顺序默认是无序的,若多个Bean间存在循环依赖或者依赖特定初始化顺序的情况,仅依赖@Autowired可能无法确保依赖项按照预期的顺序初始化。这时,明确的构造函数注入或使用@Order@DependsOn等注解控制初始化顺序更为可靠。

3.可测试性降低

​ 在单元测试中,我们通常希望模拟依赖对象以隔离待测试对象。如果过度依赖于@Autowired,那么在编写测试用例时,可能会因为Spring容器的介入而使得单元测试变得复杂且低效。相比之下,通过显式定义构造器注入或setter注入,可以更方便地替换为Mock对象进行测试。

4.隐式耦合

@Autowired注解使得类与它的依赖关系之间形成了隐式的强耦合。尽管依赖注入有助于降低模块间的耦合度,但过度依赖注解则可能导致类的设计更难以理解和修改。当查看一个类时,如果没有明确的构造函数或者setter方法显示其依赖项,开发者可能需要花费更多时间去寻找和理解这些依赖关系。

spring官方建议

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. 翻译过来就是: 强制依赖就用构造器方式注入;可选、可变的依赖就用setter注入.比如:

		private UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

但是这种方法有个缺点,如果需要注入的类很多的时候,这个构造方法就会变得很大,可读性以及后期可维护性太差,容易造成遗漏。

如何解决这个问题呢?

可以使用@RequiredArgsConstructo注解解决,这种形式就是Spring推荐使用的构造器方式注入,此种方式是lombok包下的注解,如果使用此种方式,需要项目中引入lombok,例如:

@RequiredArgsConstructor
public class UserDaoImpl{
	private final UserService userService;
}

image-20240215195929045

在这里有个注意的地方:要加上final关键字,否则会注入不成功,运行时报空指针异常

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值