这片文章是对自己学习的总结,学习材料是Java EE互联网轻量级框架整合开发 SSM框架(Spring MVC + Spring + Mybatis)和Redis实现。作者是杨开振,周吉文,梁华辉和谭茂华。
本文可单独查看,也可以接着这片文章看。
@Autowired注解自动装配确实方便,但是会出现歧义性导致系统出错。比如我们定义一个接口RoleService并装配
@Component
public interface RoleService {
@Autowired
public void RoleService(Role role);
}
然后再定义两个类实现它并装配
@Component
public class RoleService1 implements RoleService{
@Override
public void RoleService(Role role) {
System.out.println(role.sword + "1");
}
}
@Component
public class RoleService2 implements RoleService{
@Override
public void RoleService(Role role) {
System.out.println(role.sword + "2");
}
}
现在出现一个新的类要自动装配,并且自动装配的类型是RoleService1和RoleService2实现的接口
@Component
public class controller {
@Autowired
private RoleService roleService;
}
这时,容器里有两个RoleService,系统会犯迷糊不知道选哪一个来装配,让系统迷糊就是出现了错误。
解决方法是使用@Primary和@Qualifier两个注解
@Primary
自动装配出现歧义性时,有@Primary标注的类具有优先选择权。比如
@Component
@Primary
public class RoleService1 implements RoleService{
@Override
public void RoleService(Role role) {
System.out.println(role.sword + "1");
}
}
那么出现文章一开始介绍的歧义性情况是,容器会直接选择RoleService1作为自动装配的赋值。
要注意,@Primary可以标注很多个类,在上面代码的基础上,我们可以给RoleService2也加上@Primary
@Component
@Primary
public class RoleService2 implements RoleService{
@Override
public void RoleService(Role role) {
System.out.println(role.sword + "2");
}
}
这样就变成了RoleService1和RoleService2具有优先性(和其它同类相比,如果有的话),容器要从这两者中选一个,当然肯定也出错。
@Qualifier
之前有歧义性是因为@Autowired寻找Bean都是通过类型寻找,而@Qualifier则是通过名称寻找的,这就消除了歧义性。用法如下
@Autowired
@Qualifier("roleService2")
private RoleService roleService = null;
装配时直接选用id为roleService2的Bean来赋值。