为什么不推荐使用@AutoWired

为什么不推荐使用@AutoWired

  1. 使用idea开发中,idea在我们经常使用的@AutoWired注解上添加了警告

    警告内容为Field injection is not recommended

在这里插入图片描述](https://img-blog.csdnimg.cn/e0faafaa73f14ce5a3c46d6f0948da0e.png)

  1. 检验信息为Inspection info: Reports injected or autowired fields in Spring components. The quick-fix suggests the recommended constructor-based dependency injection in beans and assertions for mandatory fields.

​ 译为:检验信息:

​ 报告在Spring组件中注入或自动连接字段。

​ 快速修复建议在bean和断言中为强制字段注入基于构造函数的依赖项

为什么建议我们使用构造注入呢?

Spring常用注入方式为三种:属性注入、构造注入、setter注入。

  1. 属性注入

    @Service
    public class FuModelCoolVersionServiceImpl implements IFuModelCoolVersionService {
    	@Autowired
    	private FuModelCoolVersionMapper fuModelCoolVersionMapper;
    }
    
  2. 构造方法注入

    @Service
    public class TbldeviceBServiceImpl implements ITbldeviceBService {
    
    	private final TbldeviceBMapper tbldeviceBMapper;
    
    	public TbldeviceBServiceImpl(TbldeviceBMapper tbldeviceBMapper) {
    		this.tbldeviceBMapper = tbldeviceBMapper;
    	}
    }
    
  3. set方法注入,set方法注入一样使用@Autowired注解

   @Service
   public class TbldeviceBServiceImpl implements ITbldeviceBService {
   
   	private  TbldeviceBMapper tbldeviceBMapper;
   
   	@Autowired
   	public void setTbldeviceBMapper(TbldeviceBMapper tbldeviceBMapper) {
   		this.tbldeviceBMapper = tbldeviceBMapper;
   	}
   }

​ 4. 三种方式对比

img

​ 5. 使用属性注入的问题:

​ 1) 基于属性注入的方式,违反单一职责原则

​ 因为现在的业务一般都会使用很多依赖, 但拥有太多的依赖通常意味着承担更多的责任,而这显然违背了单一职责原则.并且类和依 赖容器强耦合,不能在容器外使用。

​ 2) 基于属性注入的方式,容易导致Spring 初始化失败

​ 初始化Spring 容器是,由于属性在被注入前就引用而导致npe(空指针),进而导致容器初始化失败。

​ java 在初始化一个类的顺序为,静态变量和静态代码块 -> 实例变量或者初始化语句 -> 构造函数 然后才会执行Spring 注解 @AutoWried 自动装配依赖,所以在执行这个类的构造方法时,依赖属性还未被注入。

​ 3) @AutoWried 是ByType注入,当存在两个类型相同的对象时就会注入失败

使用@Resource 替代 @AutoWried
  1. 如果一定要使用 属性注入,可以用@Resource 替代 @AutoWried注解

    @Resource 相当于 @AutoWried 注解,@Resource 默认按照 byName 注入。可以使用 @Qualifier指定Spring bean的name。

    @Resource装配顺序:(默认为byName)
    ①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
    ②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
    ③如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
    ④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

@Autowired, @Qualifier, @Resource, 三者有何区别
  • @Autowired: 通过byType 方式进行装配, 找不到或是找到多个,都会抛出异常。
  • @Qualifier: 如果想让@Autowired 注入的Bean进行 byName装配, 可以使用 @Qualifier 进行指定
  • @Resource :作用相当于@Autowired,只不过 @Resource 默认按照byName方式装配, 如果没有匹配, 则退回到 byType 方式进行装配。@AutoWriedSpringBeans包下的,@ResourceJavax 提供的不依赖于Spring框架,可以方便替换Ioc容器框架。
使用 lombok 优化构造注入

Lombok提供了一个注解@RequiredArgsConstructor, 可以方便我们快速进行构造注入, 例如:

@Service
@RequiredArgsConstructor
public class TbldeviceBServiceImpl implements ITbldeviceBService {

	private final TbldeviceBMapper tbldeviceBMapper;
}

如果你的项目不允许使用 lombok, 可以编写final 的属性,Alt + Enter 快捷键添加构造注入

参考文章

  • 11
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值