问题
当一个接口有2个不同实现时,使用@Autowired注解时会报org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type异常信息
解决
(1)使用Qualifier注解,选择一个对象的名称,通常比较常用
(2)Primary可以理解为默认优先选择,不可以同时设置多个,内部实质是设置BeanDefinition的primary属性
注解 | 备注 |
---|---|
@Primary |
优先方案,被注解的实现,优先被注入 |
@Qualifier |
先声明后使用,相当于多个实现起多个不同的名字,注入时候告诉我你要注入哪个 |
使用实例
一:@Qualifier
接口:
-
public
interface EmployeeService {
-
public EmployeeDto getEmployeeById(Long id);
-
}
接口对应的两个实现类: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的参数名称必须为我们之前定义@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;
-
}
-
}
扩展:
Spring注解常用汇总
使用注解之前要开启自动扫描功能,其中base-package为需要扫描的包(含子包)
@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
@Scope注解 作用域
@Lazy(true) 表示延迟初始化
@Service用于标注业务层组件、
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上)
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
@Resource 默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@DependsOn:定义Bean初始化及销毁时的顺序
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用
@Autowired @Qualifier(“personDaoBean”) 存在多个实例配合使用
原文:
https://blog.csdn.net/sinat_32023305/article/details/90718687
https://blog.csdn.net/qq_16055765/article/details/78833260