前言
在基于注解配置bean中,我们可以通过@AutoWired和@Resource进行自动注入,但是二者也有些区别,下面就来说明一下二者的基本用法和区别
@Autowired和@Resource的区别
- @Autowired不能指定id进行注入,要指定id进行注入还要使用@Qualifier进行配合才行。而@Resource可以通过name指定id
- @Autowired的注入顺序是先byType,再byName。@Resource不指定name和type,那么就是先byName,再byType
- @Autowired支持泛型依赖注入
- @Autowired官方已经不再推荐使用,建议使用@Resource
@Autowired
规则
- 使用该注解时,将会在容器中寻找要注入的类型,如果只有一个该类型,那么就直接进行注入即可
- 如果容器中有多个类型,那么会使用变量名作为id进行查找,找到则进行注入,否则抛出异常
- 如果想要实现指定id进行注入,那么可以和@Qualifier配合使用,实现指定id进行注入
验证单个类型
首先创建一个bean,名字就叫UserDao
@Repository
public class UserDao {
}
然后创建一个UserService,里面有UserDao属性
@Service
public class UserService {
@Autowired
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
}
上面的代码就表示自动注入UserDao属性,然后创建测试方法,然后运行查看控制台输出
@Test
public void t1(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
UserService userService = ioc.getBean("userService", UserService.class);
System.out.println(userService.getUserDao());
}
可以发现注入成功
验证多个类型
上面是只有一个UserDao,下面我们在xml中再配置一个
<bean class="com.ttpfx.spring.dao.UserDao"/>
同样运行上面的测试方法,发现还是成功注入
成功注入的原因是因为我们通过注解和xml都没有指定id,这样注解配置的默认id就是类名首字母小写。而xml就是全类名后面使用#进行编号,下面为容器中所有的bean
根据第二点的规则,我们下面将UserService中的UserDao属性名改为dao,继续运行改测试方法
@Service
public class UserService {
@Autowired
private UserDao dao;
public UserDao getUserDao() {
return dao;
}
}
控制台输出如下
表示容器中有多个重复的bean,而又找不到id为dao的bean
使用@Qualifier指定id
单独的@Autowired不能指定id,如果想要指定id,那么就和@Qualifier配合使用即可,我们在要@Autowired下面加上该注解,里面写上id即可
@Service
public class UserService {
@Autowired
@Qualifier("userDao")
private UserDao dao;
public UserDao getUserDao() {
return dao;
}
}
下面为测试方法控制台输出的信息
成功运行,我们就可以通过@Qualifier来进行指定id注入
特别说明
在idea中,我们将鼠标放到@Autowired上面,显示信息如下
说明@Autowired已经不推荐使用了
@Resource
这个注解可以理解为@Autowired的加强版本,可以指定id进行注入,也可以指定类型进行注入,推荐使用这个
规则
- 比较重要的2个属性是name和type,指定了name,那么就是根据id进行注入,指定了type,那么就是根据指定类型进行注入
- 如果name和type都不指定,那么先根据属性名作为id进行查找,如果找不到那么再按照类型进行查找,还是找不到就报错
通过name或type进行注入
还是使用上面的代码,只是把@Autowired改为@Resource,我们先在里面指定name,也就是指定id
@Service
public class UserService {
@Resource(name = "userDao")
private UserDao dao;
public UserDao getUserDao() {
return dao;
}
}
测试方法输出结果如下,没有问题
通过type来设置通过类型注入,就是先查找对应类型,然后看是否唯一,不唯一就在按照id进行查找,和Autowired没什么区别,就不进行测试了
name和type都不进行指定
2个都不进行指定,由于我们在容器中配置了2个UserDao,而id也没有对应的,肯定要报错,运行,控制台输出如下
@Service
public class UserService {
@Resource
private UserDao dao;
public UserDao getUserDao() {
return dao;
}
}
把属性名改为userDao,然后再运行测试方法,发现注入成功
@Service
public class UserService {
@Resource
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
}
我们不改属性名,直接将在xml中配置的另外一个UserDao删除掉,然后运行测试方法,查看输出
@Service
public class UserService {
@Resource
private UserDao dao;
public UserDao getUserDao() {
return dao;
}
}
总的来说,@Resource就是@Autowired的加强版本,建议使用这个
总结
上面验证的可能不是很完善,其他的验证还请自己用代码进行求证。总之,在spring中,进行注入建议使用@Resource。