1. 程式人生 > >Spring 註解實現Bean依賴注入之@Qualifier

Spring 註解實現Bean依賴注入之@Qualifier

三、@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();
}


相關推薦

Spring 註解實現Bean依賴注入@Qualifier

三、@Qualifier:限定描述符,用於細粒度選擇候選者; @Autowired預設是根據型別進行注入的,因此如果有多個型別一樣的Bean候選者,則需要限定其中一個候選者,否則將丟擲異常 @Qualifier限定描述符除了能根據名字進行注入,更能進行更細粒度的控制如何選擇

Spring 註解實現Bean依賴注入@Required

對應於基於XML配置中的依賴檢查,但XML配置的依賴檢查將檢查所有setter方法; 基於@Required的依賴檢查表示註解的setter方法必須,即必須通過在XML配置中配置setter注入,如果沒有配置,在容器啟動時會丟擲異常,從而保證在執行時不會遇到空指標異常,@Required只能放置在set

[學習筆記]Spring註解實現Bean

12.4  基於Java類定義Bean配置元資料 12.4.1  概述 基於Java類定義Bean配置元資料,其實就是通過Java類定義Spring配置元資料,且直接消除XML配置檔案。 基於Java類定義Bean配置元資料中的@Configuration註解的類等價於XML配置檔案

Spring註解實現Bean定義

12.3.1  概述 前邊介紹的Bean定義全是基於XML方式定義配置元資料,且在【12.2註解實現Bean依賴注入】一節中介紹了通過註解來減少配置數量,但並沒有完全消除在XML配置檔案中的Bean定義,因此有沒有方式完全消除XML配置Bean定義呢?

spring原始碼閱讀(1)- ioc依賴注入bean載入

還是先看下DefaultListableBeanFactory的類結構圖  我們從User user = (User) beanFactory.getBean("user");入手進入bean的載入管理流程。 這裡還是堅持走主線的流程,去掉無關的枝葉,儘量讓業務變得簡

spring 框架中的依賴注入(IOC--設值注入)--使用註解--的具體例項的簡單實現

體現了具體專案工程裡面的分層,dao,daoImpl,service,serviceImpl,action。讓你真正的理解這為啥分層。 順便清清楚楚的理解@Component、@Service、@Re

Spring筆記七(Types of Injection) Spring的三種依賴注入實現型別

本文研究Spring的三種依賴注入實現型別——介面注入(Interface Injection)、設值注入(Setter Injection)、構造子注入(Constructor Injection)。 Type1 介面注入: 傳統的建立介面物件的方法, 藉助介面來將呼叫者與

spring 框架中的依賴注入(IOC--設值注入)---使用xml簡單配置檔案---的具體例項的簡單實現

體現了具體專案工程裡面的分層,dao,daoImpl,service,serviceImpl,action。讓你真正的理解這為啥分層。 畢竟當年我剛剛畢業的時候,再找工作我就不是很清楚為什麼有這麼幾層

spring boot 學習(三) — 依賴注入 @Bean

spring 4推薦的@Configuration 和@bean 的用法,這樣我們可以省去繁瑣的配置檔案 第一步 建一個Maven工程 第二步新增依賴  pom.xml <?xml version="1.0" encoding="UTF-8"?> <pro

依賴注入Bean的例項化

上一篇分析到了通過遞迴的方式獲取Bean的所有依賴,接下來就該例項化Bean了。 對於例項化Bean,Spring提供了兩種方式,一種是Jdk的反射功能,還有一種就是Cglib。這兩種例項化的方式的區別是什麼呢? 依賴注入的起點是getBean方法,然後

Spring 學習筆記 - IOC/依賴注入

簡述: Spring 學習 - IOC/依賴注入 1. Bean 的例項化 1) 直接使用原始類建立bean <bean id="exampleBean" class="com.anialy.test.ExampleBean" /> 2) 使用工廠方法建立

1.Spring、IOC與依賴注入

 Spring概述 Spring是分層的Java SE/EE應用 full-stack輕量級開源框架,以IoC(Inverse Of Control:反轉控制)和 AOP(Aspect Oriented Programming:面向切面程式設計)為核心,提供了展現層Spr

spring3零配置註解實現Bean定義(包括JSR-250、JSR-330)

 註解實現Bean定義  概述 前邊介紹的Bean定義全是基於XML方式定義配置元資料,且在【12.2註解實現Bean依賴注入】一節中介紹了通過註解來減少配置數量,但並沒有完全消除在XML配置檔案中的Bean定義,因此有沒有方式完全消除XML配置Be

5.spring:註解配置 Bean

在classpath中掃描元件 組鍵掃描:能夠從classpath下自動掃描,偵測和例項化具有特定註解的元件 特定的元件包括: ->@Componment:基於註解,標識一個受Spring管理的組鍵 ->@Respository:標識持久層元件 ->@Service:標識服務層 ->

Spring容器和bean注入(1)

第一節 在IOC容器中裝配Bean 1.1Spring容器成功啟動條件 1.匯入Spring框架相關的jar包 2.正確配置spring配置檔案 3.Bean的類都已放到應用程式的類路徑下 1.2Bean配置資訊的組成 Bean配置資

Spring(17) 依賴注入後的行為

其實就是在對bean進行各種賦值初始化後讓bean執行某個動作。 可以讓bean實現InitializingBean介面,然後重寫afterProperties()方法,這樣就可以讓bean在初始化之後自動執行afterProperties()方法。

Spring 控制反轉(IOC) | 依賴注入(DI)的解析

學習過Spring框架的人一定都會聽過Spring的IoC(控制反轉) 、DI(依賴注入)這兩個概念,對於初學Spring的人來說,總覺得IoC 、DI這兩個概念是模糊不清的,是很難理解的,今天和大家分享網上的一些技術大牛們對Spring框架的IOC的理解以及談談我對Spri

Spring AOP切面類依賴注入的正確姿勢

在某些場景下需要將Spring的Bean注入到Spring AOP切面的屬性中。 類似下面程式碼: @Aspect public class SomeAspect { @Inject private SomeService someService; @Be

Spring學習筆記一(Spring容器和bean注入

第一節 在IOC容器中裝配Bean 1.1Spring容器成功啟動條件 1.匯入Spring框架相關的jar包 2.正確配置spring配置檔案 3.Bean的類都已放到應用程式的類路徑下 1.2Bean配置資訊的組成 Bean配置資訊是Bean的元資料資訊(

spring 註解裝配bean (裝配bean 二)

註解裝配bean 最簡單的例子 @Component("role") public class Role { @Value("1") private Long id; @Value("zhangsan") private String roleNam