@Qualifier注解

@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.  
  3. public interface DataSource {

  4.  
  5. public void connection();

  6. }

MysqlDriveManagerDataSource.java

 

 
  1. package com.bean;

  2.  
  3. public class MysqlDriveManagerDataSource implements DataSource{

  4.  
  5. public void connection() {

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

  7. }

  8.  
  9. }

OracleDriveManagerDataSource.java

 

 
  1. package com.bean;

  2.  
  3. public class OracleDriveManagerDataSource implements DataSource{

  4.  
  5. public void connection() {

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

  7. }

  8.  
  9. }

TestBean.java

 

 
  1. package com.bean;

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

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

  5.  
  6.  
  7. public class TestBean {

  8.  
  9. private DataSource dataSource;

  10.  
  11. @Autowired

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

  13. this.dataSource = dataSource;

  14. }

  15.  
  16. public DataSource getDataSource() {

  17. return dataSource;

  18. }

  19. }

其中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.  
  5. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

  6. <qualifier value="oracleDataSource"/>

  7. </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.  
  12. try{

  13. ctx.getBean("mysqlDataSource");

  14. }catch(Exception e){

  15. if(e instanceof NoSuchBeanDefinitionException){

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

  17. }

  18. e.printStackTrace();

  19. }

  20. }

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

 

 

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

1、准备测试Bean:

 

 
  1. package com.bean;

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

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

  5.  
  6.  
  7. public class TestBean {

  8.  
  9. private DataSource dataSource;

  10.  
  11. @Autowired

  12. @Qualifier(value="mysqlDataSourceBean")

  13. public void initDataSource(DataSource dataSource){

  14. this.dataSource = dataSource;

  15. }

  16.  
  17. public DataSource getDataSource() {

  18. return dataSource;

  19. }

  20. }

 

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.  
  12. }

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

@Qualifier(value="mysqlDataSourceBean")

 

 

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

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

 

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

 

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

 

 
  1. package com.annotation;

  2.  
  3. import java.lang.annotation.ElementType;

  4. import java.lang.annotation.Retention;

  5. import java.lang.annotation.RetentionPolicy;

  6. import java.lang.annotation.Target;

  7.  
  8. import org.springframework.beans.factory.annotation.Qualifier;

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

  11. @Retention(RetentionPolicy.RUNTIME)

  12. @Qualifier

  13. public @interface Mysql {

  14. }

 
  1. package com.annotation;

  2.  
  3. import java.lang.annotation.ElementType;

  4. import java.lang.annotation.Retention;

  5. import java.lang.annotation.RetentionPolicy;

  6. import java.lang.annotation.Target;

  7.  
  8. import org.springframework.beans.factory.annotation.Qualifier;

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

  11. @Retention(RetentionPolicy.RUNTIME)

  12. @Qualifier

  13. public @interface Oracle {

  14. }

 

2、准备测试Bean:

 

 
  1. package com.bean;

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

  4.  
  5. import com.annotation.Mysql;

  6. import com.annotation.Oracle;

  7.  
  8. public class TestBean {

  9.  
  10. private DataSource mysqlDataSource;

  11.  
  12. private DataSource oracleDataSource;

  13.  
  14. @Autowired

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

  16. this.mysqlDataSource = mysqlDataSource;

  17. this.oracleDataSource = oracleDataSource;

  18. }

  19.  
  20. public DataSource getMysqlDataSource() {

  21. return mysqlDataSource;

  22. }

  23.  
  24. public DataSource getOracleDataSource() {

  25. return oracleDataSource;

  26. }

  27. }

 

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.  
  6. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

  7. <qualifier value="oracleDataSource"/>

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

  9. </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.  
  3. public enum DataBase {

  4. ORACLE,MYSQL;

  5. }

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

 

 
  1. package com.annotation;

  2.  
  3. import java.lang.annotation.ElementType;

  4. import java.lang.annotation.Retention;

  5. import java.lang.annotation.RetentionPolicy;

  6. import java.lang.annotation.Target;

  7.  
  8. import org.springframework.beans.factory.annotation.Qualifier;

  9.  
  10. import com.enumBean.DataBase;

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

  13. @Retention(RetentionPolicy.RUNTIME)

  14. @Qualifier

  15. public @interface DataSourceType {

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

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

  18. }

3、准备测试Bean:

 

 
  1. package com.bean;

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

  4.  
  5. import com.annotation.DataSourceType;

  6. import com.enumBean.DataBase;

  7.  
  8. public class TestBean {

  9.  
  10. private DataSource mysqlDataSource;

  11.  
  12. private DataSource oracleDataSource;

  13.  
  14. @Autowired

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

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

  17. this.mysqlDataSource = mysqlDataSource;

  18. this.oracleDataSource = oracleDataSource;

  19. }

  20.  
  21. public DataSource getMysqlDataSource() {

  22. return mysqlDataSource;

  23. }

  24.  
  25. public DataSource getOracleDataSource() {

  26. return oracleDataSource;

  27. }

  28. }

 

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.  
  9. <bean id="oracleDataSourceBean" class="com.bean.OracleDriveManagerDataSource">

  10. <qualifier value="oracleDataSource"/>

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

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

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

  14. </qualifier>

  15. </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

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值