天天看點

【淺談JavaEE架構】Spring中@Autowired标簽與@Resource标簽的差別

@Autowired 

Spring 2.5 引入了 @Autowired 注釋,它可以對類成員變量、方法及構造函數進行标注,完成自動裝配的工作。 

通過 @Autowired的使用來消除 set ,get方法。

要實作我們要精簡程式的目的。

@Autowired預設按照類型進行注入

@Autowired @Qualifier("personDaoxxx")這樣就是按照名稱進行裝配

@Autowired(required=true)必須注入值,不能為null,為false無論注入什麼值都是null

autowire屬性取值如下:

byType:按類型裝配,可以根據屬性的類型,在容器中尋找根該類型比對的bean.如果發現多個,那麼将會抛出異常。如果沒有找到,即屬性值為null。

byName:按名稱裝配,可以根據屬性的名稱,在容器中尋找根該屬性名相同的bean,如果沒有找到,即屬性值為null。

Constructor與byType的方式類似,不同之處在于它應用于構造器參數。如果在容器中沒有找到與構造器參數類型一緻的bean,那麼将會抛出異常。

Autodetect:通過bean類的自省機制來決定是使用constructor還是byType方式進行自動裝配。如果發現預設的構造器,那麼将使用byType方式。

====================================================================================================

Spring中@Autowired标簽與@Resource标簽的差別 

強烈建議 放棄@Autowire 使用@Resource 原因 spring支援标準 

Spring支援JSR-250注解

Spring不但支援自己定義的@Autowired注解,還支援由JSR-250規範定義的幾個注解,如:@Resource、 @PostConstruct及@PreDestroy。

 1. @Autowired

     @Autowired是Spring 提供的,需導入

     Package:org.springframework.beans.factory.annotation.Autowired;

     隻按照byType 注入。

 2. @Resource

     @Resource預設按 byName 自動注入,是J2EE提供的, 需導入Package:  

     javax.annotation.Resource;

     @Resource有兩個中重要的屬性:name和type ,而Spring将@Resource注解的name屬性解析為bean的

     名字,而type屬性則解析為bean的類型。是以如果使用name屬性,則使用byName的自動注入政策,而使用

     type屬性時則使用 byType自動注入政策。如果既不指定name也不指定type屬性,這時将通過反射機制使用by

     Name自動注入政策。

     @Resource裝配順序 

   (1). 如果同時指定了name和type,則從Spring上下文中找到唯一比對的bean進行裝配,找不到則抛出異常;

   (2). 如果指定了name,則從上下文中查找名稱(id)比對的bean進行裝配,找不到則抛出異常;

   (3). 如果指定了type,則從上下文中找到類型比對的唯一bean進行裝配,找不到或者找到多個,都會抛出異常;

   (4). 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有比對,則回退為一

     個原始類型進行比對,如果比對則自動裝配;

     @Resource的作用相當于@Autowired,隻不過@Autowired按byType自動注入。

 3. 使用差別

     @Resource(name="loginService") 

     private LoginService loginService;

     @Autowired(required=false)@Qualifier("loginService") 

    (1).@Autowired 與@Resource都可以用來裝配bean. 都可以寫在字段上,或寫在setter方法上;

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

     (3).@Resource(這個注解屬于J2EE的),預設安裝名稱進行裝配,名稱可以通過name屬性進行指定,如果沒

     有指定name屬性,當注解寫在字段上時,預設取字段名進行安裝名稱查找,如果注解寫在setter方法上預設取屬

     性名進行裝配。當找不到與名稱比對的bean時才按照類型進行裝 配。但是需要注意的是,如果name屬性一旦指

     定,就隻會按照名稱進行裝配。

     推薦使用@Resource注解在字段上,這樣就不用寫setter方法了.并且這個注解是屬于J2EE的,減少了與Spring的耦合,這樣代碼看起就比較優雅 。

另外,通過實踐,還總結出一條規律:

如果将@requied或者@autowired寫了set方法之上,則程式會走到set方法内部。

但如果寫在了field之上,則不會進入set方法當中。

@Autowired預設按類型裝配,@Resource預設按名稱裝配,當找不到與名稱比對的bean才會按類型裝配。

------------------------------------------------------------------------------------------------

細節問題總結:

1.當我們進行測試時,用ApplicationContext對象的getBean()方法尋找元件。在之前的配置檔案中我們會用<bean>标簽的id屬性去定義,在使用自動掃描注解後怎樣獲得組建的id呢?

在這種情況下,Spring會将被标注注解的類名,然後再将該類名的第一個字母變為小寫,放到getBean()方法中。如:UserBizImpl類的元件Id就會是userBizImpl,擷取時為context.getBean("userBizImpl");

那麼,我們在使用注解時可以自定義元件的Id嗎?

當然可以。我們需要在為相應的類添加注解時,在注解之後添加自定義的類名,例如:

當我們在擷取該元件時,為context.getBean("userBiz);

2.在配置檔案中我們可以對元件(bean)的作用域範圍進行設定,它的預設值是單例模式,那麼在添加注解的情況下,我們怎樣設定元件的作用域範圍呢?

我們可以直接在為類添加注解的同時,運用另一個注解@Scope("prototype")來設定,如下

3.在使用注解時,為元件設定初始化和銷毀方法:

在添加注解的相應的類中,如果想初始化或銷毀某個方法,我們可以直接在方法上添加注解,如下:

4.在使用Spring自動掃描元件後,怎樣進行依賴注入?

運用注解@Resource和@Autowired,并為依賴對象設定名稱,例如:

首先它會根據名稱去找Spring自動掃描的并加入到Spring容器的元件(bean),如果有相同的名稱,則進行依賴注入,如果沒有相同的名稱。則會根據類型區尋找元件。

了解以上的内容後,你就可以很輕松的實作spirng零配置。

項目後期開發工作 定義了大量的bean,現在需要為每個資料庫操作添加 日志記錄,是以就定義了一個logBiz,

如果按照通常的做法,需要修改所有的配置檔案 添加property屬性,現在使用自動注入機制。

在baseAction中添加通用日志方法,留出一個IogBiz接口,在繼承的子類action中,定義一個logBiz屬性 并用@Resouce 注解即可。