天天看點

Spring XML配置--使用注解裝配(@Atutowired、@Inject、@Resource)

陳科肇--http://blog.csdn.net/u013474104/article/details/44352765

=======

1.裝配術語

建立應用對象之間協作關系的行為通常被稱為裝配

2.使用注解裝配

Spring是從Spring2.5開始引入使用注解自動裝配的。

Spring容器是預設禁用注解裝配的,是以如果要使用Spring的注解裝配,你必須啟用它。啟用方式:使用Spring的context命名空間配置中的<context:annotation-config>元素,配置啟用如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<!-- 
		spring預設是禁用注解裝配,添加下行代碼可啟用
		spring支援幾種不同的用于自動裝配的注解
		Spring自帶的@Autowired
		JSR-330的@Inject
		JSR-250的@Resource 
	-->
	<context:annotation-config />
</beans>
           

一旦配置完成,我們就可以對代碼添加注解,辨別Spring應該為屬性、方法和構造器進行自動裝配

好了,我們可以看到上述的配置的自動裝配配置中,spring支援幾種不同的用于自動裝配的注解,接下來我就詳解下使用各個不同注解進行自動裝配。

三者的差別,我是網上搜尋的,就截圖就OK了:

Spring XML配置--使用注解裝配(@Atutowired、@Inject、@Resource)

3.4種類型的自動裝配

當涉及自動裝配Bean的依賴關系時,Spring有多種處理的方式。是以,Spring提供了4種各具特色的自動裝配政策。

a.byName:把與Bean的屬性具有相同名字(或者ID)的其他Bean自動裝配到Bean的對應屬性中。如果沒有,則不進行裝配;

b.byType:把與Bean的屬性具有相同類型的其它Bean自動裝配到Bean的對應屬性中。如果沒有,則不進行裝配;

c.constructor:把與Bean的構造器入參具有相同類型的其他Bean自動裝配到Bean構造器的對應入參中;

d.autodetect:首先嘗試constructor進行自動裝配。如果失敗,再嘗試使用byType進行自動裝配;

4.Spring自帶的@Autowired

首先,@Autowired可以對Bean的屬性可以進行多種裝配方式,比如屬性的setter方法、Bean引用的任意方法、構造器以及可以使用@Autowired直接标注屬性,并删除setter方法,比如:

注:在執行@Autowired注解時,Spring就會嘗試對該方法執行byType自動裝配

HelloWord對象有一個helloChina屬性的對象,我們要對helloChina進行注解裝配!

1.setter方法
@Autowired
public void setHelloChina(HelloChina helloChina){
	this.helloChina=helloChina;
}
2.任意方法
@Autowired
public void xx(HelloChina helloChina){
	this.helloChina=helloChina;
}
3.構造器
@Autowired
public HelloWord(HelloChina helloChina){
	this.helloChina=helloChina;
}
4.删除setter方法
@Autowired
private HelloChina helloChina;
           

看,@Autowired甚至不會受限于private關鍵字,那是不是@Autowired注解沒有任何限制了呢?

其實并不是這樣的,@Autowired注解的确存在兩種阻礙我們工作的場景。具體來說,應該中必須隻能有一個Bean适合裝配到@Autowired注解所辨別的屬性或參數中。如果沒有比對的Bean,或者存在多個比對的Bean,@Autowired注解就會遇到一些麻煩(異常:NoSuchBeanDefinitionException)。

這類型麻煩的解決方案如下:

a.可選的自動裝配

屬性不一定非要裝配,null值也即可接受:

@Autowired(required=false)
private HelloChina helloChina;
           

表示的是,如果沒有找到HelloChina進行裝配,則helloChina為null值;

注:required屬性可以用于@Autowired注解所使用的任意地方。但用于構造器裝配時,隻有一個構造器可以将@Autowired的required屬性設定為true。其他使用@Autowired注解所辨別的構造器隻能将required屬性設定為false。此外,使用@Autowired辨別多個構造器時,Spring就會從所有滿足裝配條件的構造器中選擇入參數最多的那個構造器;

b.限定歧義性的依賴

當Bean的屬性有多個适合自動裝配的Bean時,那麼@Autowired應該使用那個Bean呢?這時@Autowired就不知道了。

這時為了确定,我們需要裝配的Bean時,可以配合使用@Qualifier來明确指定名為xxName的Bean。

@Autowired
@Qualifier("xxName")
private HelloChina helloChina;
           

如上所示,@Qualifier注解嘗試注入ID為xxName的Bean。

原理,也即是将byType自動裝配轉換為byName自動裝配。

@Qualifier限定器,還可以自個建立,即滿足不了我們的需求時,這時就不介紹了,有需要的google去吧;

5.JSR-330的@Inject

為了統一各種依賴注入架構的程式設計模型,JCP最近釋出了java依賴注入規範,JCP将其稱為JSR-330,@Inject注解是JSR-330的核心部件。該注解幾乎可以完全替代Spring的@Autowired注解。是以除了使用Spring特定的@Autowired注解,我們可以選擇@Inject。

和@Autowired一個,@Inject可以用來自動裝配屬性、方法和構造器;與@Autowired不同的是,@Inject沒有required屬性。是以@Inject注解注入的依賴關系必須存在,否則報異常。

與@Autowired一樣,@Inject有自己限定的方法,即處理限定歧義性的依賴,配置如下:

@Autowired
@Named("xxName")
private HelloChina helloChina;
           

另外,@Inject還可以建立自己的Qualifier,這裡就不扯了....

注:實際上,@Named注解就是一個使用@Qualifier注解所标注的注解

6.在注解中注入表達式:

Spring3.0引入了@Value,可以讓我們使用注解裝配String類型的值和基本類型的值,例如:int、boolean。

@Value("陳科肇")
private String myName;
           

上述純屬為寫死了,你們可能會問,把值定死有什麼意義。

@Value+SpEL表達式才能展現出來強大魔力,這裡就不講解了,有興趣的去google吧....