1. 程式人生 > >Spring4--在IoC容器中裝配Bean

Spring4--在IoC容器中裝配Bean

背景

本章的重點是介紹如何裝配Bean。

1.Spring配置概述

Bean配置資訊是Bean的元資料資訊,它由四個方面組成:

(1)Bean的實現類;

(2)Bean的屬性資訊,如資料來源的連線數、使用者名稱、密碼等;

(3)Bean的依賴關係,Spring根據依賴關係配置完成Bean之間的裝配;

(4)Bean的行為配置,如生命週期範圍及生命週期各過程的回撥函式等。

Bean元資料資訊在Spring容器中的內部對應物是由BeanDefinition形成的Bean登錄檔。

下面這張圖描述了Spring容器、Bean配置資訊、Bean實現類及應用程式之間的相互關係:

基於xml的配置,spring採用Schema格式。spring配置的Schema檔案放置在各模組JAR檔案內一個名為config的目錄下。

2.依賴注入

(1)屬性注入指通過setXxx()方法注入Bean的屬性值或依賴物件。Spring只會檢查Bean中是否有對應的Setter方法,至於

Bean中是否有對應的屬性成員變更則不做要求。Spring配置檔案中<property>元素所指定的屬性名和Bean實現類的Setter

方法滿足Sun JavaBean的屬性命名規範:xxx的屬性對應 setXxx()方法。JavaBean的變數的前兩個字母要麼全部大寫,要

麼全部小寫。

(2)建構函式注入,它能保證一些必要的屬性在Bean例項化就得到設定,確保Bean例項化後就可以使用。Spring容器能對構

造函式配置的Bean進行例項化的前提是,即建構函式入參引用的物件必須已經準備就緒。如果兩個Bean都採用建構函式注入,

而且都通過建構函式入參引用對方,就會發生類似於執行緒死鎖的迴圈依賴問題。解決辦法是修改Bean的程式碼,將建構函式注入

方式調整為屬性注入方式。

(3)工廠方法注入。Spring IoC容器以框架的方式提供工廠方法的功能,並以透明的方式開放給開發者,所以很少需要手工編寫

基於工廠方法的類。

3.注入引數詳解

(1)字面值,指可用字串表示的值,這些值可以通過<value>元素標籤進行注入。Spring容器在內部為字面值提供了編輯器,

它可以將以字串表示的字面值轉換為內部變數的相應型別。

如果配置檔案中的注入值包括下面的特殊字元,可以採用<![CDATA[]]>特殊標籤,將包含特殊字元的字串封裝起來,另一個

辦法是使用xml轉義序列表示特殊字元。

(2)引用其他Bean,<ref>元素可以通過下面3個屬性引用容器中的其他Bean:

1.bean:通過該屬性可以引用同一容器或父容器中的Bean;

2.local:通過該屬性只能引用同一配置檔案中定義的Bean;

3.parent:引用父容器中的Bean。

(3)內部Bean,沒有名字,不能被其他Bean引用,只能在宣告處為外部Bean提供例項注入。

(4)null值,必須使用專用的<null/>元素標籤。

(5)級聯屬性。

(6)集合型別屬性,List、Set、Map、Properties。可以通過util名稱空間配置集合型別的Bean。

(7)簡化配置方式:

字面值屬性簡化:

引用物件屬性:<ref local="xxx">和<ref parent="xxx">沒有對應的簡化形式

使用P名稱空間:為了簡化xml檔案的配置,越來越多的xml檔案採用屬性而子元素配置資訊。通過<bean>元素屬性的方式配置

Bean的屬性。

對於字面值屬性  p:<屬性名>=“xxx”  ;  對於引用物件的屬性  p:<屬性名>-ref="xxx"

由於p名稱空間的屬性名師可變的,所以p名稱空間沒有對應的Schema定義檔案。

(8)自動裝配,Spring IoC容器可以按照某種規則對容器中的Bean進行自動裝配,而無須通過顯式的方式進行依賴配置。<bean>

元素提供了一個指定自動裝配型別的屬性 autowire="<自動裝配型別>"。Spring提供了四種自動裝配型別:

<beans>元素標籤中的default-autowire屬性可以配置全域性自動匹配,預設值為no,表示不啟用自動裝配。

在實際開發中,xml配置方式很少啟用自動裝配功能,而基於註解的配置方式預設採用byType自動裝配策略。

4.方法注入

Spring IoC容器擁有複寫Bean方法的能力,歸功於CGLib類包。CGLib可以在執行期動態操作Class位元組碼,為Bean動態

建立子類或實現類。lookup方法注入使用範圍,一般是希望通過一個singleton Bean 獲取一個prototype Bean時使用。

方法替換,可以使用某個Bean的方法去替換另一個Bean的方法,具體怎麼操作看書。

5.<bean>之間的關係

(1)繼承,如果多個<bean>存在相同的配置資訊,則Spring允許定義一個父<bean>,子<bean>將自動繼承父<bean>的配置

資訊。父<bean>宣告為abstract="true",子<bean>用parent="xxx"指定父<bean>。

(2)依賴,使用<ref>元素標籤建立對其他Bean的依賴關係。通過depends-on屬性顯式制定Bean前置依賴的Bean,前置依賴

Bean會在本Bean例項化之前建立好。

(3)引用,一個<bean>引用另一個<bean>的id屬性值,目的是在執行期通過getBean(beanName)方法獲取對應的Bean。通過

使用 <idref>元素標籤,在容器啟動時,Spring會檢查引用關係的正確性,這樣就可以提前發現錯誤。

6.整合多個配置檔案

在啟動Spring容器時,可以通過一個String陣列指定這些配置檔案,Spring還允許通過<import>將多個配置檔案引入到一個文

件中,進行配置檔案的整合。

7.Bean作用域

Bean作用域型別:

通過scppe="<作用域型別>" 來指定。還可以自定義Bean的作用域,不過這個比較少用。

(1)singleton,無狀態或者狀態不可變的類適合使用單例模式。

 如果不希望容器在啟動時提前例項化singleton的Bean,可以通過lazy-init屬性進行控制。

(2)prototype,在預設情況下,Spring容器在啟動時不例項化prototype的Bean。Spring容器將prototype的Bean交給呼叫者後,

就不再管理它的生命週期。

(3)其他三個是與Web應用環境相關的Bean作用域,在使用之前需要在Web容器中進行額外的配置。利用HTTP請求監聽器

進行配置。

兩個監聽器的區別:

ServletContextListener負責監聽Web容器啟動和關閉的事件,ServletRequestListener監聽HTTP請求事件,Web伺服器接收

到的每一次請求都會通知該監聽器。

(3)如果將Web相關作用域的Bean注入singleton或prototype的Bean中,我們需要是使用SpringAOP建立代理。 

8.FactoryBean

通過實現該工廠類介面定製例項化Bean的邏輯,它隱藏了例項化一些複雜Bean的細節,給上層應用帶來了便利。

9.基於註解的配置

(1)除了@Component外,Spring還提供了3個功能基本和@Component等效的註解,分別對應DAO、Service及Web層的Controller進行註解:

[email protected]:用於對Dao實現類進行標註。

[email protected]:用於對Service實現類進行標註。

[email protected]:用於對Controller實現類進行標註。

(2)掃描註解定義的Bean,Spring提供了一個context名稱空間,它提供了通過掃描類包以應用註解定義Bean的方式。也可以

通過contex定義過濾的規則,把不要的類過濾掉。

(3)自動裝配Bean,使用@Autowired進行自動注入。@Autowired預設按型別(byType)配置的方式在容器中查詢匹配的Bean。

在對類方法進行標註時,Spring將自動選擇匹配入參型別Bean進行注入。建議在方法上標註@Autowired註解,在單元測試時就

比較方便。

10.基於java類的配置

普通的pojo只要標註@Configuration註解,就可以為Spring容器提供Bean定義的資訊,每個標註了@Bean的類方法都相當於

提供了一個Bean的定義資訊。

11.基於Groovy DSL的配置

這個稍微看一下,以後要用到再詳細看。

12.通過編碼方式動態新增Bean

(1)通過DefaultListableBeanFactory,可以擴充套件配置、迴圈列舉,實現Bean動態注入,除此之外還要實現BeanFactoryPostProcessor介面。

(2)擴充套件自定義標籤,需要經過一下步驟:

1.採用XSD描述自定義標籤的元素屬性;

2.編寫Bean定義的解析器;

3.註冊自定義標籤解析器;

4.繫結名稱空間解析器。

13.不同配置方式比較

Bean不同配置方式的使用場景:

總結

這一章詳細地介紹了Bean的配置,受益匪淺。