为什么不推荐使用@AutoWired
-
使用idea开发中,idea在我们经常使用的
@AutoWired
注解上添加了警告警告内容为
Field injection is not recommended
- 检验信息为:
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注入。
-
属性注入
@Service public class FuModelCoolVersionServiceImpl implements IFuModelCoolVersionService { @Autowired private FuModelCoolVersionMapper fuModelCoolVersionMapper; }
-
构造方法注入
@Service public class TbldeviceBServiceImpl implements ITbldeviceBService { private final TbldeviceBMapper tbldeviceBMapper; public TbldeviceBServiceImpl(TbldeviceBMapper tbldeviceBMapper) { this.tbldeviceBMapper = tbldeviceBMapper; } }
-
set方法注入,set方法注入一样使用
@Autowired
注解
@Service
public class TbldeviceBServiceImpl implements ITbldeviceBService {
private TbldeviceBMapper tbldeviceBMapper;
@Autowired
public void setTbldeviceBMapper(TbldeviceBMapper tbldeviceBMapper) {
this.tbldeviceBMapper = tbldeviceBMapper;
}
}
4. 三种方式对比
5. 使用属性注入的问题:
1) 基于属性注入的方式,违反单一职责原则
因为现在的业务一般都会使用很多依赖, 但拥有太多的依赖通常意味着承担更多的责任,而这显然违背了单一职责原则.并且类和依 赖容器强耦合,不能在容器外使用。
2) 基于属性注入的方式,容易导致Spring 初始化失败
初始化Spring 容器是,由于属性在被注入前就引用而导致npe(空指针),进而导致容器初始化失败。
java 在初始化一个类的顺序为,静态变量和静态代码块 -> 实例变量或者初始化语句 -> 构造函数 然后才会执行Spring 注解
@AutoWried
自动装配依赖,所以在执行这个类的构造方法时,依赖属性还未被注入。 3)
@AutoWried
是ByType注入,当存在两个类型相同的对象时就会注入失败
使用@Resource
替代 @AutoWried
-
如果一定要使用 属性注入,可以用
@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
方式进行装配。@AutoWried
是SpringBeans
包下的,@Resource
是Javax
提供的不依赖于Spring框架,可以方便替换Ioc容器框架。
使用 lombok 优化构造注入
Lombok
提供了一个注解@RequiredArgsConstructor
, 可以方便我们快速进行构造注入, 例如:
@Service
@RequiredArgsConstructor
public class TbldeviceBServiceImpl implements ITbldeviceBService {
private final TbldeviceBMapper tbldeviceBMapper;
}
如果你的项目不允许使用 lombok
, 可以编写final 的属性,Alt
+ Enter
快捷键添加构造注入