1. 程式人生 > >Spring 註釋 @Autowired 和@Resource 的區別

Spring 註釋 @Autowired 和@Resource 的區別

一、

@Autowired和@Resource都可以用來裝配bean,都可以寫在欄位上,或者方法上。

二、

@Autowired屬於Spring的;@Resource為JSR-250標準的註釋,屬於J2EE的。

三、

@Autowired預設按型別裝配,預設情況下必須要求依賴物件必須存在,如果要允許null值,可以設定它的required屬性為false,例如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier註解進行使用,如下:

@Autowired() 
@Qualifier("baseDao")
private BaseDao baseDao;

四、

@Resource,預設安裝名稱進行裝配,名稱可以通過name屬性進行指定,如果沒有指定name屬性,當註解寫在欄位上時,預設取欄位名進行安裝名稱查詢,如果註解寫在setter方法上預設取屬性名進行裝配。當找不到與名稱匹配的bean時才按照型別進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。

 例如:

@Resource(name="baseDao")
private BaseDao baseDao;

五、

推薦使用:@Resource註解在欄位上,這樣就不用寫setter方法了,並且這個註解是屬於J2EE的,減少了與spring的耦合。這樣程式碼看起就比較優雅。

遇到的問題

@Autowired @Qualifier("cipShopOwnerServiceImpl")   bean name ShopOwnerService cipShopOwnerServiceImpl; ShopOwnerService 需要是介面 cipShopOwnerServiceImpl bean的名字

ShopOwnerService是介面,兩個實現類 @Component("cipShopOwnerServiceImpl")   bean name public class CIPShopOwnerServiceImpl implements ShopOwnerService {} 和

@Component("shopOwnerServiceImpl")       bean name public class ShopOwnerServiceImpl implements ShopOwnerService {}

直接 @Autowired CipShopOwnerServiceImpl cipShopOwnerServiceImpl; 報錯

  @Autowired //    @Qualifier("cipShopOwnerServiceImpl")     ShopOwnerService cipShopOwnerServiceImpl;     可以

 @Autowired //    @Qualifier("cipShopOwnerServiceImpl")     ShopOwnerService pShopOwnerServiceImpl;     報錯 確定cipShopOwnerServiceImpl 最好是bean name 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 配置檔案的方法

我們編寫spring框架的程式碼時候。一直遵循是這樣一個規則:所有在spring中注入的bean都建議定義成私有的域變數。並且要配套寫上get和set方法。  Boss擁有Office和Car型別的兩個屬性:

public class Boss {        private Car car;        private Office office;        //省略 get/setter        @Override       public String toString()     {            return "car:" + car + "/n" + "office:" + office;        }    }    1 2 3 4 5 6 7 8 9 10 11 我們在Spring容器中將Office和Car宣告為Bean,並注入到Boss Bean中,下面是使用傳統XML完成這個工作的配置檔案beans.xml:

<?xml version="1.0" encoding="UTF-8" ?>    <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">        <bean id="boss" class="Boss">            <property name="car" ref="car"/>            <property name="office" ref="office" />        </bean>        <bean id="office" class="Office">            <property name="officeNo" value="002"/>        </bean>        <bean id="car" class="Car" scope="singleton">            <property name="brand" value="紅旗CA72"/>            <property name="price" value="2000"/>        </bean>    </beans> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 當我們執行以下程式碼時,控制檯將正確打出boss的資訊:

import org.springframework.context.ApplicationContext;    import org.springframework.context.support.ClassPathXmlApplicationContext;    public class Test {   

    public static void main(String[] args)     {            String[] locations = {"beans.xml"};            ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);            Boss boss = (Boss) ctx.getBean("boss");            System.out.println(boss);        }    }  1 2 3 4 5 6 7 8 9 10 11 12 13 @Autowired的使用

Spring 2.5引入了@Autowired註釋,它可以對類成員變數、方法及建構函式進行標註,完成自動裝配的工作。通過@Autowired的使用來消除set,get方法。  下面是@Autowired的定義:

@Retention(RetentionPolicy.RUNTIME)   @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD}) public @interface Autowired { //是否必須滿足依賴性檢查,預設時,凡是應用了@Autowired註解的屬性和方法都必須找到合適的協作者,否則Spring容器會丟擲異常, //通過調整required屬性取值能夠改變這一行為。 boolean required() default true; }  1 2 3 4 5 6 7 8 注意:@Autowired註解能夠作用於構建器、屬性、方法。這裡的方法不侷限於設值方法,即setter方法,常見的各種方法都可以應用這一註解。  要使用@Autowired實現我們要精簡程式的目的,需要這樣來處理:  在applicationContext.xml中加入:

<!-- 該 BeanPostProcessor 將自動對標註 @Autowired 的 Bean 進行注入 -->    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> 1 2 Spring通過一個BeanPostProcessor對@Autowired進行解析,所以要讓@Autowired起作用必須事先在Spring容器中宣告AutowiredAnnotationBeanPostProcessor Bean。  修改在原來注入Spirng容器中的bean的方法,在域變數上加上標籤@Autowired,並且去掉相應的get和set方法。  使用 @Autowired 註釋的 Boss.java

import org.springframework.beans.factory.annotation.Autowired;    public class Boss {        @Autowired       private Car car;        @Autowired       private Office office;    }   1 2 3 4 5 6 7 8 在applicatonContext.xml中把原來引用的標籤也去掉。

<?xml version="1.0" encoding="UTF-8" ?>    <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">   

    <!-- 該 BeanPostProcessor 將自動起作用,對標註 @Autowired 的 Bean 進行自動注入 -->        <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>   

    <!-- 移除 boss Bean 的屬性注入配置的資訊 -->        <bean id="boss" class="Boss"/>   

    <bean id="office" class="Office">            <property name="officeNo" value="001"/>        </bean>        <bean id="car" class="Car" scope="singleton">            <property name="brand" value="紅旗 CA72"/>            <property name="price" value="2000"/>        </bean>    </beans> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 這樣,當 Spring容器啟動時,AutowiredAnnotationBeanPostProcessor將掃描Spring容器中所有Bean,當發現Bean中擁有@Autowired 註釋時就找到和其匹配(預設按型別匹配)的Bean,並注入到對應的地方中去。

@Autowired注入規則

@Autowired預設是按照byType進行注入的,但是當byType方式找到了多個符合的bean,又是怎麼處理的?Autowired預設先按byType,如果發現找到多個bean,則又按照byName方式比對,如果還有多個,則報出異常。  例子:

@Autowired private Car redCar; 1 2 spring先找型別為Car的bean 如果存在且唯一,則OK; 如果不唯一,在結果集裡,尋找name為redCar的bean。因為bean的name有唯一性,所以,到這裡應該能確定是否存在滿足要求的bean了  @Autowired也可以手動指定按照byName方式注入,使用@Qualifier標籤,例如:  @Autowired()  @Qualifier(“baseDao” )  因為bean的name具有唯一性,理論上是byName會快一點,但spring預設使用byType的方式注入。另外補充一點:@Resource(這個註解屬於J2EE的)的標籤,預設是按照byName方式注入的。 ---------------------