本人工作中普遍常见使用@Autowired完成依赖注入,自从出来工作后都没使用过其他注入方式,专门写这一篇依赖注入方式的文章主要是想让自己动手敲一下代码,毕竟纸上得来终觉浅,绝知此事要躬行。
先介绍一下三种方式:
@Autowired默认按类型装配
@Qualifier和Autowired配合使用,指定bean的名称
@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
@Service
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier
private UserDao userDao;
@Resource
private LevelService levelService;
}
工作开发中发现直接在变量上注解 @Autowired,它会有个警告提示:Field injection is not recommended。尽管我们经常忽略这个警告,但至少要明白它为什么要警告。
Inspection info: Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".
翻译为:检查信息:Spring Team 建议:“始终在您的 bean 中使用基于构造函数的依赖注入。始终对强制依赖项使用断言”。
原来是官方建议我们使用构造函数方式的依赖注入,可以理解。 Field Injection 这种注入方式虽然简单,代码又少,可存在明显的弊端:
@Service
public class UserServiceImpl implements UserService {
private final UserDao userDao;
private final LevelService levelService;
public UserServiceImpl(UserDao userDao, LevelService levelService) {
this.userDao = userDao;
this.levelService = levelService;
}
}
构造器依赖注入通过容器触发一个类的构造器来实现的,通过强制指明依赖注入来保证这个类的运行,防止NullPointerException;
可以使用final关键字修饰,另外重要的一点是能避免循环依赖,如果存在循环依赖,Spring项目启动的时候就会报错;
那么多优势我们都不用,可能我们都是简洁型选手。
注意:重写构造函数注入时不需加 @Autowired或@Resource。
@Service
public class UserServiceImpl implements UserService {
private UserDao userDao;
private LevelService levelService;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Autowired
public void setLevelService(LevelService levelService) {
this.levelService = levelService;
}
注意:使用Setter注入时需要加 @Autowired或@Resource,不使用的话 注入的依赖是为 NULL。
注入对象不能使用final修饰。
我感觉吧,强烈推荐使用官方推荐的构造函数方式注入。
但是吧,如果我的项目中Bean的名字规范且都是单实现,又不考虑使用final关键字修饰,然后避免掉注入属性是空指针的情况,我还是想用@Autowired。
留言与评论(共有 0 条评论) “” |