问题
当一个接口有2个不同实现时,使用@Autowired注解时会报org.springframework.beans.factory.NoUniqueBeanDefinitionException异常信息
解决
(1)使用Qualifier注解,选择一个对象的名称,通常比较常用
(2)Primary可以理解为默认优先选择,不可以同时设置多个,内部实质是设置BeanDefinition的primary属性
注解 | 备注 |
---|---|
@Primary | 优先方案,被注解的实现,优先被注入 |
@Qualifier | 先声明后使用,相当于多个实现起多个不同的名字,注入时候告诉我你要注入哪个 |
使用实例
一:@Qualifier
接口:
public interface EmployeeService {
public EmployeeDto getEmployeeById(Long id);
}
接口对应的两个实现类:EmployeeServiceImpl和EmployeeServiceImpl1:接口对应的两个实现类:EmployeeServiceImpl和EmployeeServiceImpl1:
@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmployeeDto();
}
}
@Service("employeeService1")
public class EmployeeServiceImpl1 implements EmployeeService {
public EmployeeDto getEmployeeById(Long id) {
return new EmployeeDto();
}
}
这个时候就要用到@Qualifier注解了,qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的,我们修改调用代码,添加@Qualifier注解,需要注意的是@Qualifier的参数名称必须为我们之前定义@Service注解的名称之一!
@Controller
@RequestMapping("/emplayee.do")
public class EmployeeInfoControl {
@Autowired
@Qualifier("employeeService")
EmployeeService employeeService;
@RequestMapping(params = "method=showEmplayeeInfo")
public void showEmplayeeInfo(HttpServletRequest request, HttpServletResponse response, EmployeeDto dto) {
//#略
}
}
二、@Primary:和@Qualifier 一样,@Primary也一样,使用场景经常是:在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary 的作用就出来了。
简单例子:
接口:
public interface Singer {
String sing(String lyrics);
}
有下面的两个实现类:
@Component // 加注解,让spring识别
public class MetalSinger implements Singer{
@Override
public String sing(String lyrics) {
return "I am singing with DIO voice: "+lyrics;
}
}
@Primary
@Component
public class OperaSinger implements Singer{
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}