三、@Qualifier:限定描述符,用于细粒度选择候选者;
@Autowired默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常
@Qualifier限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,具体使用方式如下:
@Qualifier(value = "限定标识符")
字段、方法、参数
(1)、根据基于XML配置中的
其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的
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配置:
我们使用@Qualifier("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();
}
}
从测试可以看出使用
(2)、缺省的根据Bean名字注入:最基本方式,是在Bean上没有指定
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配置:
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配置:
4、在Spring修改定义的两个数据源:
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配置:
5、在Spring修改定义的两个数据源:
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();
}