@Qualifier注解
@Autowired是根据类型进行自动装配的。如果当spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。如下:
①可能存在多个UserDao实例
[java] view plain copy
- @Autowired
- @Qualifier("userServiceImpl")
- public IUserService userService;
或者
[java] view plain copy
- @Autowired
- public void setUserDao(@Qualifier("userDao") UserDao userDao) {
- this.userDao = userDao;
- }
这样Spring会找到id为userServiceImpl和userDao的bean进行装配。
②可能不存在UserDao实例
[java] view plain copy
- @Autowired(required = false)
- public IUserService userService
三、@Qualifier:限定描述符,用于细粒度选择候选者;
@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常
@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,具体使用方式如下:
@Qualifier(value = "限定标识符")
字段、方法、参数
(1)、根据基于XML配置中的<qualifier>标签指定的名字进行注入,使用如下方式指定名称:
<qualifier type="org.springframework.beans.factory.annotation.Qualifier" value="限定标识符"/>
其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的。
1、准备测试Bean:
DataSource.java
package com.bean;
public interface DataSource {
public void connection();
}
MysqlDriveManagerDataSource.java
package com.bean;
public class MysqlDriveManagerDataSource implements DataSource{
public void connection() {
System.out.println("mysql database connecting...");
}
}
OracleDriveManagerDataSource.java
package com.bean;
public class OracleDriveManagerDataSource implements DataSource{
public void connection() {
System.out.println("oracle database connecting...");
}
}
TestBean.java
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class TestBean {
private DataSource dataSource;
@Autowired
public void initDataSource(@Qualifier("oracleDataSource") DataSource dataSource){
this.dataSource = dataSource;
}
public DataSource getDataSource() {
return dataSource;
}
}
其中TestBean.java中使用 @Qualifier还有一种方式
@Autowired
@Qualifier(value="oracleDataSource")
public void initDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
2、在Spring配置文件 添加如下Bean配置:
<bean id="testBean" class="com.bean.TestBean"/>
我们使用@Qualifier("oracleDataSource")来指定候选Bean的限定标识符,我们需要在配置文件中使用<qualifier>标签来指定候选Bean的限定标识符“oracleDataSource”:
<bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">
<qualifier value="mysqlDataSource"/>
</bean>
<bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">
<qualifier value="oracleDataSource"/>
</bean>
3、测试方法如下:
@Test
public void autowiredTest(){
TestBean bean = ctx.getBean("testBean", TestBean.class);
DataSource dataSource = bean.getDataSource();
if(dataSource instanceof MysqlDriveManagerDataSource){
System.out.println("mysql");
}else if(dataSource instanceof OracleDriveManagerDataSource){
System.out.println("oracle");
}
dataSource.connection();
try{
ctx.getBean("mysqlDataSource");
}catch(Exception e){
if(e instanceof NoSuchBeanDefinitionException){
System.out.println("@Qualifier不能作为Bean的标识符");
}
e.printStackTrace();
}
}
从测试可以看出使用<qualifier>标签指定的限定标识符只能被@Qualifier使用,不能作为Bean的标识符,如“ctx.getBean("mysqlDataSource")”是获取不到Bean的。
(2)、缺省的根据Bean名字注入:最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,但如果你指定了<qualifier>标签将不会发生容错。
1、准备测试Bean:
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class TestBean {
private DataSource dataSource;
@Autowired
@Qualifier(value="mysqlDataSourceBean")
public void initDataSource(DataSource dataSource){
this.dataSource = dataSource;
}
public DataSource getDataSource() {
return dataSource;
}
}
2、在Spring配置文件 添加如下Bean配置:
<bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource"/>
<bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource"/>
3、测试方法如下:
@Test
public void autowiredTest(){
TestBean bean = ctx.getBean("testBean", TestBean.class);
DataSource dataSource = bean.getDataSource();
if(dataSource instanceof MysqlDriveManagerDataSource){
System.out.println("mysql");
}else if(dataSource instanceof OracleDriveManagerDataSource){
System.out.println("oracle");
}
dataSource.connection();
}
因为配置文件中并没有使用 @Qualifier标签 所以我们在bean中注入的时候是注入 bean
@Qualifier(value="mysqlDataSourceBean")
(3)、扩展@Qualifier限定描述符注解(不带参数):对@Qualifier的扩展来提供细粒度选择候选者;
具体使用方式就是自定义一个注解并使用@Qualifier注解其即可使用。
首先让我们考虑这样一个问题,如果我们有两个数据源,分别为Mysql和Oracle,因此注入两者相关资源时就牵扯到数据库相关,如在DAO层注入SessionFactory时,当然可以采用前边介绍的方式,但为了简单和直观我们希望采用自定义注解方式。
1、扩展@Qualifier限定描述符注解来分别表示Mysql和Oracle数据源
package com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Mysql {
}
package com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Oracle {
}
2、准备测试Bean:
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import com.annotation.Mysql;
import com.annotation.Oracle;
public class TestBean {
private DataSource mysqlDataSource;
private DataSource oracleDataSource;
@Autowired
public void initDataSource(@Mysql DataSource mysqlDataSource, @Oracle DataSource oracleDataSource){
this.mysqlDataSource = mysqlDataSource;
this.oracleDataSource = oracleDataSource;
}
public DataSource getMysqlDataSource() {
return mysqlDataSource;
}
public DataSource getOracleDataSource() {
return oracleDataSource;
}
}
3、在Spring配置文件 添加如下Bean配置:
<bean id="testBean" class="com.bean.TestBean"/>
4、在Spring修改定义的两个数据源:
<bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">
<qualifier value="mysqlDataSource"/>
<qualifier type="com.annotation.Mysql"/>
</bean>
<bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">
<qualifier value="oracleDataSource"/>
<qualifier type="com.annotation.Oracle"/>
</bean>
5、测试方法如下:
@Test
public void autowiredTest(){
TestBean bean = ctx.getBean("testBean", TestBean.class);
DataSource dataSource = bean.getMysqlDataSource();
if(dataSource instanceof MysqlDriveManagerDataSource){
System.out.println("mysql");
}else if(dataSource instanceof OracleDriveManagerDataSource){
System.out.println("oracle");
}
dataSource.connection();
}
测试也通过了,说明我们扩展的@Qualifier限定描述符注解也能很好工作。
(3)、扩展@Qualifier限定描述符注解(带参数):对@Qualifier的扩展来提供细粒度选择候选者;
前边演示了不带属性的注解,接下来演示一下带参数的注解:
1、首先定义数据库类型:
package com.enumBean;
public enum DataBase {
ORACLE,MYSQL;
}
2、其次扩展@Qualifier限定描述符注解
package com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
import com.enumBean.DataBase;
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface DataSourceType {
String ip(); //指定ip,用于多数据源情况
DataBase database(); //指定数据库类型
}
3、准备测试Bean:
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import com.annotation.DataSourceType;
import com.enumBean.DataBase;
public class TestBean {
private DataSource mysqlDataSource;
private DataSource oracleDataSource;
@Autowired
public void initDataSource(@DataSourceType(ip="localhost",database=DataBase.MYSQL) DataSource mysqlDataSource,
@DataSourceType(ip="localhost",database=DataBase.ORACLE) DataSource oracleDataSource){
this.mysqlDataSource = mysqlDataSource;
this.oracleDataSource = oracleDataSource;
}
public DataSource getMysqlDataSource() {
return mysqlDataSource;
}
public DataSource getOracleDataSource() {
return oracleDataSource;
}
}
4、在Spring配置文件 添加如下Bean配置:
<bean id="testBean" class="com.bean.TestBean"/>
5、在Spring修改定义的两个数据源:
<bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">
<qualifier value="mysqlDataSource"/>
<qualifier type="com.annotation.DataSourceType">
<attribute key="ip" value="localhost"/>
<attribute key="database" value="MYSQL"/>
</qualifier>
</bean>
<bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">
<qualifier value="oracleDataSource"/>
<qualifier type="com.annotation.DataSourceType">
<attribute key="ip" value="localhost"/>
<attribute key="database" value="ORACLE"/>
</qualifier>
</bean>
6、测试方法如下:
@Test
public void autowiredTest(){
TestBean bean = ctx.getBean("testBean", TestBean.class);
DataSource dataSource = bean.getMysqlDataSource();
if(dataSource instanceof MysqlDriveManagerDataSource){
System.out.println("mysql");
}else if(dataSource instanceof OracleDriveManagerDataSource){
System.out.println("oracle");
}
dataSource.connection();
}
转载地址:https://blog.csdn.net/qq_38989725/article/details/76592791
https://blog.csdn.net/lovin_fang/article/details/78537547
@Qualifier注解相关推荐
- 在方法的形参位置使用@Qualifier注解||@Autowired 与@Resource的区别
实验21:在方法的形参位置使用@Qualifier注解 实验22:@Autowired注解的required属性指定某个属性允许不被设置 @Autowired @Resource @Inject ...
- 请举例说明@Qualifier 注解?
@Qualifier 注解意味着可以在被标注bean 的字段上可以自动装配.Qualifier 注解可以用来取消Spring不能取消的bean 应用.
- Spring学习(10)--- @Qualifier注解
按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以指定单独的构造器参数或方法参数 可用于注解集合类型变量 例子: package c ...
- java中qualifier注解怎么写_Java 注解 Qualifier
有如下接口: public interfaceEmployeeService {publicEmployeeDto getEmployeeById(Long id); } 同时有下述两个实现类 Emp ...
- spring的@primary和@qualifier注解解决一个接口多个实现的注入问题
spring的@primary和@qualifier注解解决一个接口多个实现的注入问题 参考文章: (1)spring的@primary和@qualifier注解解决一个接口多个实现的注入问题 (2) ...
- 23 SpringBoot @Qualifier注解
//定义亚洲人 @Qualifier("Asian") @Component public class AsianMan extends Person {}········//定义 ...
- @Qualifier注解的使用
1:当一个接口的方法,对应多个实现的时候,怎么区分到底注入哪一个 @Service public interface MyService{public int findSomeone(); }//第一 ...
- @Primary和@Qualifier注解
@Primary和@Qualifier注解,都是处理@Autowired注入时,发现多个相同类型的冲突时,进行解决. 实际项目中,@Autowired,默认是byType注入,当发现多个实现类的时候, ...
- Qualifier注解
字面理解 首先,字面意思,显然它是单词Qualify的一个变形,把y改i加er.Qualify是质量的意思.而Qualifier有合格者的意思. 合格者在这里有啥意思,显然,翻译之后我更困惑了.[检查 ...
最新文章
- seaborn clustermap详解及绘制
- HTML5的data-*自定义属性
- 南京信息工程大学滨江学院计算机科学与技术专业,南京信息工程大学滨江学院有哪些专业及什么专业好...
- java 模拟form_java模拟form上传数据
- Python入门1_数字表达式
- 物联网技术或颠覆传统高等教育
- debugfs dd恢复误删数据
- mysql数据库技术_MySQL数据库技术(13)[组图]_MySQL
- android 自定义View【2】对话框取色色盘取色的实现
- Ping32文档透明加密软件基础概念
- RuoYi(若依)平台页面缓存无效
- Docker 启动 MySQL 最佳实践
- Linux作业 使用make命令和分析makefile文件
- 毕业后的去向:继续读研还是直接就业?
- 安全合规/GDPR--15--通用数据保护条例-目录索引
- android 图标弹跳动画,动效教程 | 5 分钟快速做个弹跳加载小动画
- 时隔多年,我胡汉三又回来了
- deepin 输入法频繁重启,无法正常输入汉字解决方法
- W5500以太网控制器芯片(三):实现DHCP服务
- RateLimiter google限流组件试析(SmoothBursty/SmoothWarmingUp)