@Autowired是根据类型进行自动装配的。如果当spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。如下:

①可能存在多个UserDao实例

[java] view plain copy

  1. @Autowired
  2. @Qualifier("userServiceImpl")
  3. public IUserService userService;

或者

[java] view plain copy

  1. @Autowired
  2. public void setUserDao(@Qualifier("userDao") UserDao userDao) {
  3. this.userDao = userDao;
  4. }

这样Spring会找到id为userServiceImpl和userDao的bean进行装配。

②可能不存在UserDao实例

[java] view plain copy

  1. @Autowired(required = false)
  2. public IUserService userService

三、@Qualifier:限定描述符,用于细粒度选择候选者;

@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常

@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,具体使用方式如下:

  1. @Qualifier(value = "限定标识符")

  2. 字段、方法、参数

(1)、根据基于XML配置中的<qualifier>标签指定的名字进行注入,使用如下方式指定名称:

<qualifier  type="org.springframework.beans.factory.annotation.Qualifier"  value="限定标识符"/> 

其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的。

1、准备测试Bean:

DataSource.java

  1. package com.bean;

  2. public interface DataSource {

  3. public void connection();

  4. }

MysqlDriveManagerDataSource.java

  1. package com.bean;

  2. public class MysqlDriveManagerDataSource implements DataSource{

  3. public void connection() {

  4. System.out.println("mysql database connecting...");

  5. }

  6. }

OracleDriveManagerDataSource.java

  1. package com.bean;

  2. public class OracleDriveManagerDataSource implements DataSource{

  3. public void connection() {

  4. System.out.println("oracle database connecting...");

  5. }

  6. }

TestBean.java

  1. package com.bean;

  2. import org.springframework.beans.factory.annotation.Autowired;

  3. import org.springframework.beans.factory.annotation.Qualifier;

  4. public class TestBean {

  5. private DataSource dataSource;

  6. @Autowired

  7. public void initDataSource(@Qualifier("oracleDataSource") DataSource dataSource){

  8. this.dataSource = dataSource;

  9. }

  10. public DataSource getDataSource() {

  11. return dataSource;

  12. }

  13. }

其中TestBean.java中使用 @Qualifier还有一种方式

  1. @Autowired

  2. @Qualifier(value="oracleDataSource")

  3. public void initDataSource(DataSource dataSource){

  4. this.dataSource = dataSource;

  5. }

2、在Spring配置文件 添加如下Bean配置:

<bean id="testBean" class="com.bean.TestBean"/>

我们使用@Qualifier("oracleDataSource")来指定候选Bean的限定标识符,我们需要在配置文件中使用<qualifier>标签来指定候选Bean的限定标识符“oracleDataSource”:

  1. <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">

  2. <qualifier value="mysqlDataSource"/>

  3. </bean>

  4. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

  5. <qualifier value="oracleDataSource"/>

  6. </bean>

3、测试方法如下:

  1. @Test

  2. public void autowiredTest(){

  3. TestBean bean = ctx.getBean("testBean", TestBean.class);

  4. DataSource dataSource = bean.getDataSource();

  5. if(dataSource instanceof MysqlDriveManagerDataSource){

  6. System.out.println("mysql");

  7. }else if(dataSource instanceof OracleDriveManagerDataSource){

  8. System.out.println("oracle");

  9. }

  10. dataSource.connection();

  11. try{

  12. ctx.getBean("mysqlDataSource");

  13. }catch(Exception e){

  14. if(e instanceof NoSuchBeanDefinitionException){

  15. System.out.println("@Qualifier不能作为Bean的标识符");

  16. }

  17. e.printStackTrace();

  18. }

  19. }

从测试可以看出使用<qualifier>标签指定的限定标识符只能被@Qualifier使用,不能作为Bean的标识符,如“ctx.getBean("mysqlDataSource")”是获取不到Bean的。

(2)、缺省的根据Bean名字注入最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,但如果你指定了<qualifier>标签将不会发生容错。

1、准备测试Bean:

  1. package com.bean;

  2. import org.springframework.beans.factory.annotation.Autowired;

  3. import org.springframework.beans.factory.annotation.Qualifier;

  4. public class TestBean {

  5. private DataSource dataSource;

  6. @Autowired

  7. @Qualifier(value="mysqlDataSourceBean")

  8. public void initDataSource(DataSource dataSource){

  9. this.dataSource = dataSource;

  10. }

  11. public DataSource getDataSource() {

  12. return dataSource;

  13. }

  14. }

2、在Spring配置文件 添加如下Bean配置:

  1. <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource"/>

  2. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource"/>

3、测试方法如下:

  1. @Test

  2. public void autowiredTest(){

  3. TestBean bean = ctx.getBean("testBean", TestBean.class);

  4. DataSource dataSource = bean.getDataSource();

  5. if(dataSource instanceof MysqlDriveManagerDataSource){

  6. System.out.println("mysql");

  7. }else if(dataSource instanceof OracleDriveManagerDataSource){

  8. System.out.println("oracle");

  9. }

  10. dataSource.connection();

  11. }

因为配置文件中并没有使用 @Qualifier标签 所以我们在bean中注入的时候是注入 bean

@Qualifier(value="mysqlDataSourceBean")

(3)、扩展@Qualifier限定描述符注解(不带参数):对@Qualifier的扩展来提供细粒度选择候选者;

具体使用方式就是自定义一个注解并使用@Qualifier注解其即可使用。

首先让我们考虑这样一个问题,如果我们有两个数据源,分别为Mysql和Oracle,因此注入两者相关资源时就牵扯到数据库相关,如在DAO层注入SessionFactory时,当然可以采用前边介绍的方式,但为了简单和直观我们希望采用自定义注解方式。

1、扩展@Qualifier限定描述符注解来分别表示Mysql和Oracle数据源

  1. package com.annotation;

  2. import java.lang.annotation.ElementType;

  3. import java.lang.annotation.Retention;

  4. import java.lang.annotation.RetentionPolicy;

  5. import java.lang.annotation.Target;

  6. import org.springframework.beans.factory.annotation.Qualifier;

  7. @Target({ElementType.TYPE,ElementType.FIELD,ElementType.PARAMETER})

  8. @Retention(RetentionPolicy.RUNTIME)

  9. @Qualifier

  10. public @interface Mysql {

  11. }

  1. package com.annotation;

  2. import java.lang.annotation.ElementType;

  3. import java.lang.annotation.Retention;

  4. import java.lang.annotation.RetentionPolicy;

  5. import java.lang.annotation.Target;

  6. import org.springframework.beans.factory.annotation.Qualifier;

  7. @Target({ElementType.TYPE,ElementType.FIELD,ElementType.PARAMETER})

  8. @Retention(RetentionPolicy.RUNTIME)

  9. @Qualifier

  10. public @interface Oracle {

  11. }

2、准备测试Bean:

  1. package com.bean;

  2. import org.springframework.beans.factory.annotation.Autowired;

  3. import com.annotation.Mysql;

  4. import com.annotation.Oracle;

  5. public class TestBean {

  6. private DataSource mysqlDataSource;

  7. private DataSource oracleDataSource;

  8. @Autowired

  9. public void initDataSource(@Mysql DataSource mysqlDataSource, @Oracle DataSource oracleDataSource){

  10. this.mysqlDataSource = mysqlDataSource;

  11. this.oracleDataSource = oracleDataSource;

  12. }

  13. public DataSource getMysqlDataSource() {

  14. return mysqlDataSource;

  15. }

  16. public DataSource getOracleDataSource() {

  17. return oracleDataSource;

  18. }

  19. }

3、在Spring配置文件 添加如下Bean配置:

<bean id="testBean" class="com.bean.TestBean"/>

4、在Spring修改定义的两个数据源:

  1. <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">

  2. <qualifier value="mysqlDataSource"/>

  3. <qualifier type="com.annotation.Mysql"/>

  4. </bean>

  5. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

  6. <qualifier value="oracleDataSource"/>

  7. <qualifier type="com.annotation.Oracle"/>

  8. </bean>

5、测试方法如下:

  1. @Test

  2. public void autowiredTest(){

  3. TestBean bean = ctx.getBean("testBean", TestBean.class);

  4. DataSource dataSource = bean.getMysqlDataSource();

  5. if(dataSource instanceof MysqlDriveManagerDataSource){

  6. System.out.println("mysql");

  7. }else if(dataSource instanceof OracleDriveManagerDataSource){

  8. System.out.println("oracle");

  9. }

  10. dataSource.connection();

  11. }

测试也通过了,说明我们扩展的@Qualifier限定描述符注解也能很好工作。

(3)、扩展@Qualifier限定描述符注解(带参数):对@Qualifier的扩展来提供细粒度选择候选者;

前边演示了不带属性的注解,接下来演示一下带参数的注解:

1、首先定义数据库类型:

  1. package com.enumBean;

  2. public enum DataBase {

  3. ORACLE,MYSQL;

  4. }

2、其次扩展@Qualifier限定描述符注解

  1. package com.annotation;

  2. import java.lang.annotation.ElementType;

  3. import java.lang.annotation.Retention;

  4. import java.lang.annotation.RetentionPolicy;

  5. import java.lang.annotation.Target;

  6. import org.springframework.beans.factory.annotation.Qualifier;

  7. import com.enumBean.DataBase;

  8. @Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})

  9. @Retention(RetentionPolicy.RUNTIME)

  10. @Qualifier

  11. public @interface DataSourceType {

  12. String ip(); //指定ip,用于多数据源情况

  13. DataBase database(); //指定数据库类型

  14. }

3、准备测试Bean:

  1. package com.bean;

  2. import org.springframework.beans.factory.annotation.Autowired;

  3. import com.annotation.DataSourceType;

  4. import com.enumBean.DataBase;

  5. public class TestBean {

  6. private DataSource mysqlDataSource;

  7. private DataSource oracleDataSource;

  8. @Autowired

  9. public void initDataSource(@DataSourceType(ip="localhost",database=DataBase.MYSQL) DataSource mysqlDataSource,

  10. @DataSourceType(ip="localhost",database=DataBase.ORACLE) DataSource oracleDataSource){

  11. this.mysqlDataSource = mysqlDataSource;

  12. this.oracleDataSource = oracleDataSource;

  13. }

  14. public DataSource getMysqlDataSource() {

  15. return mysqlDataSource;

  16. }

  17. public DataSource getOracleDataSource() {

  18. return oracleDataSource;

  19. }

  20. }

4、在Spring配置文件 添加如下Bean配置:

<bean id="testBean" class="com.bean.TestBean"/>

5、在Spring修改定义的两个数据源:

  1. <bean id="mysqlDataSourceBean" class="com.bean.MysqlDriveManagerDataSource">

  2. <qualifier value="mysqlDataSource"/>

  3. <qualifier type="com.annotation.DataSourceType">

  4. <attribute key="ip" value="localhost"/>

  5. <attribute key="database" value="MYSQL"/>

  6. </qualifier>

  7. </bean>

  8. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

  9. <qualifier value="oracleDataSource"/>

  10. <qualifier type="com.annotation.DataSourceType">

  11. <attribute key="ip" value="localhost"/>

  12. <attribute key="database" value="ORACLE"/>

  13. </qualifier>

  14. </bean>

6、测试方法如下:

  1. @Test

  2. public void autowiredTest(){

  3. TestBean bean = ctx.getBean("testBean", TestBean.class);

  4. DataSource dataSource = bean.getMysqlDataSource();

  5. if(dataSource instanceof MysqlDriveManagerDataSource){

  6. System.out.println("mysql");

  7. }else if(dataSource instanceof OracleDriveManagerDataSource){

  8. System.out.println("oracle");

  9. }

  10. dataSource.connection();

  11. }

转载地址:https://blog.csdn.net/qq_38989725/article/details/76592791

https://blog.csdn.net/lovin_fang/article/details/78537547

@Qualifier注解相关推荐

  1. 在方法的形参位置使用@Qualifier注解||@Autowired 与@Resource的区别

    实验21:在方法的形参位置使用@Qualifier注解 实验22:@Autowired注解的required属性指定某个属性允许不被设置 @Autowired   @Resource  @Inject ...

  2. 请举例说明@Qualifier 注解?

    @Qualifier 注解意味着可以在被标注bean 的字段上可以自动装配.Qualifier 注解可以用来取消Spring不能取消的bean 应用.

  3. Spring学习(10)--- @Qualifier注解

    按类型自动装配可能多个bean实例的情况,可以使用Spring的@Qualifier注解缩小范围(或指定唯一),也可以指定单独的构造器参数或方法参数 可用于注解集合类型变量 例子: package c ...

  4. java中qualifier注解怎么写_Java 注解 Qualifier

    有如下接口: public interfaceEmployeeService {publicEmployeeDto getEmployeeById(Long id); } 同时有下述两个实现类 Emp ...

  5. spring的@primary和@qualifier注解解决一个接口多个实现的注入问题

    spring的@primary和@qualifier注解解决一个接口多个实现的注入问题 参考文章: (1)spring的@primary和@qualifier注解解决一个接口多个实现的注入问题 (2) ...

  6. 23 SpringBoot @Qualifier注解

    //定义亚洲人 @Qualifier("Asian") @Component public class AsianMan extends Person {}········//定义 ...

  7. @Qualifier注解的使用

    1:当一个接口的方法,对应多个实现的时候,怎么区分到底注入哪一个 @Service public interface MyService{public int findSomeone(); }//第一 ...

  8. @Primary和@Qualifier注解

    @Primary和@Qualifier注解,都是处理@Autowired注入时,发现多个相同类型的冲突时,进行解决. 实际项目中,@Autowired,默认是byType注入,当发现多个实现类的时候, ...

  9. Qualifier注解

    字面理解 首先,字面意思,显然它是单词Qualify的一个变形,把y改i加er.Qualify是质量的意思.而Qualifier有合格者的意思. 合格者在这里有啥意思,显然,翻译之后我更困惑了.[检查 ...

最新文章

  1. seaborn clustermap详解及绘制
  2. HTML5的data-*自定义属性
  3. 南京信息工程大学滨江学院计算机科学与技术专业,南京信息工程大学滨江学院有哪些专业及什么专业好...
  4. java 模拟form_java模拟form上传数据
  5. Python入门1_数字表达式
  6. 物联网技术或颠覆传统高等教育
  7. debugfs dd恢复误删数据
  8. mysql数据库技术_MySQL数据库技术(13)[组图]_MySQL
  9. android 自定义View【2】对话框取色色盘取色的实现
  10. Ping32文档透明加密软件基础概念
  11. RuoYi(若依)平台页面缓存无效
  12. Docker 启动 MySQL 最佳实践
  13. Linux作业 使用make命令和分析makefile文件
  14. 毕业后的去向:继续读研还是直接就业?
  15. 安全合规/GDPR--15--通用数据保护条例-目录索引
  16. android 图标弹跳动画,动效教程 | 5 分钟快速做个弹跳加载小动画
  17. 时隔多年,我胡汉三又回来了
  18. deepin 输入法频繁重启,无法正常输入汉字解决方法
  19. W5500以太网控制器芯片(三):实现DHCP服务
  20. RateLimiter google限流组件试析(SmoothBursty/SmoothWarmingUp)

热门文章

  1. ScriptManager updatepanel
  2. ElasticSearch 常用的查询过滤语句
  3. 2016点滴生活:收获与展望
  4. Array的内置方法api
  5. 投资理财-如何看公司
  6. mysql5.7新特性--官方高可用方案MGR介绍
  7. php 二维排序函数,PHP二维数组排序函数
  8. 你了解C语言中的输入函数吗?
  9. c语言mkdir函数,c函数mkdir无法创建目录,该怎么处理
  10. 关于U3D的面试题及各种坑