Spring XML配置Bean標籤詳解
前段時間回顧Spring的一些技術和資訊,自己去試著配置框架進行練習,這裡就分享一下Spring bean配置的各種標籤方便自己去配置資訊,
beans: 整個配置檔案的根節點,包含一個或多個Bean元素。在該標記中可配置名稱空間與schema的裝載路徑,還可以通過default-init-method屬性為該配置檔案中的所有Bean例項統一指定初始化方法,通過default-destroy-method屬性為該配置檔案中的所有Bean例項統一指定銷燬方法,通過default-lazy-init屬性為該配置檔案中的所有Bean例項統一指定是否進行遲延載入
bean標記:
用該標記定義一個Bean的例項化資訊,用以指導Bean工廠正確地進行Bean的生產與裝配。由class屬性指定類全名,由id(推薦使用)或name屬性指定生成的Bean例項名稱。init-method屬性指定初始化時要呼叫的方法,destroy-method屬性例項銷燬時要呼叫的方法。Bean例項的依賴關係可通過property子標記(set方式注入)或constructor-arg子標記(構造方式注入)來定義。bean標記中的scope屬性用以設定Bean例項的生成方式,當scope設定為singleton或預設時以單例模式生成,當scope設定為prototype時則以原型(多例)模式生成。
constructor-arg標記:
它是bean標記的子標記,用以傳入構造引數進行例項化,這也是注入依賴關係的一種常見方式。index屬性指定構造引數的序號(從0開始),當只有一個構造引數是通常省略不寫;type屬性指定構造引數的型別,當為基本資料型別時亦可省略此屬性;引數值可通過ref屬性或value屬性直接指定,也可以通過ref或value子標記指定
property:它是bean標記的子標記,用以呼叫Bean例項中的相關Set方法完成屬性值的賦值,從而完成依賴關係的注入
name:知道bean例項的屬性名稱
ref屬性或value屬性直接指定,也可以通過ref或value子標記指定
ref標記:
該標記通常作為constructor-arg、property、list、set、entry等標記的子標記,由bean屬性指定一
個Bean工廠中某個Bean例項的引用
value標記:該標記通常作為constructor-arg、property、list、set、entry等標記的子標記,用以直接指定一個常
量值
list標記:該標記用以封裝List或陣列型別屬性的依賴注入(即賦值),具體的元素通過ref或value子標記
指定
set標記:該標記用以封裝Set型別屬性的依賴注入(即賦值),具體的元素通過ref或value子標記指定
map標記:標記用以封裝Map型別屬性的依賴注入(即賦值),具體的元素通過entry子標記指定
entry標記:該標記通常用做map標記的子標記,用以設定一個“鍵/值”對。key屬性接收字串型別的“鍵”名稱,“值”則可由ref或value子標記指定
props標記:
該標記用以封裝Properties型別屬性的依賴注入(即賦值),具體的元素通過prop子標記指定
prop標記:該標記通常用做props標記的子標記,用以設定一個“鍵/值”對。key屬性接收字串型別的“鍵”名稱,“值”則可放置在prop標記體內
null標記:該標記用於賦一個null值,與在Java中直接為某個屬性賦null值效果等同
配置bean例項 :User的bean建立例項時加入了原型的作用域
<?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">
<!-- 建立 SimpleDateFormat 例項並對這個例項進行例項化-->
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
<!-- 對構造引數進行例項化 -->
<constructor-arg value="yyyy年MM月dd hh時mm分ss秒"/>
</bean>
<!-- 建立User 類的例項 並對例項的屬性進行賦值 作用域是原型 不設定 scope 時作用域是 單例 -->
<bean id="user" class="test.spring.bean.User">
<property name="name" value="小明"/>
<property name="password" value="123456"/>
</bean>
<!-- 建立Data例項: -->
<bean id="data" class="java.util.Date"></bean>
<!-- 建立 test.spring.bean.XmlIocBean bean的例項 init-method初始化,相當與呼叫了init方法 destroy-method銷燬的方法: -->
<bean id="xmlIocBean" class="test.spring.bean.XmlIocBean"
init-method="myInit" destroy-method="myDestroy">
<!-- constructor-arg標記用以傳入構造引數進行例項化 index 是從構造器傳參的順序 0開始 type:引數的型別 ref賦值: -->
<constructor-arg index="0" type="java.text.SimpleDateFormat" ref="simpleDateFormat"/>
<constructor-arg index="1" type="java.util.Date" ref="data"></constructor-arg>
<!-- bean 中的屬性進行賦值 intnumber 陣列-->
<property name="intnumber">
<list>
<value>2</value>
<value>15</value>
<value>7</value>
</list>
</property>
<!-- list 屬性賦值: 賦值bean物件-->
<property name="list">
<list>
<ref bean="user"/>
<ref bean="user"/>
</list>
</property>
<!-- Set 屬性賦值: 賦值bean物件-->
<property name="set">
<set>
<ref bean="user"/>
<ref bean="user"/>
</set>
</property>
<!-- Map 屬性賦值:key是直接賦值 value key2是ref bean賦值一個類的例項 -->
<property name="map">
<map>
<entry key="key1">
<value>key1元素的值</value>
</entry>
<entry key="key2">
<ref bean="user"></ref>
</entry>
</map>
</property>
<!-- 物件建立例項化,並進行賦值 -->
<property name="props">
<props>
<prop key="prop1">properties元素1 </prop>
<prop key="prop2">properties元素2 </prop>
</props>
</property>
</bean>
</beans>
這這裡出現過問題:
User類中,我當時建立構造器,的時候傳了引數,那麼在配置檔案中必須要為建構函式賦值:
建立 simpleDateFormat 的例項bean的時候,我打算給他property標記使用賦值,這個是當前例項bean中的屬性進行賦值,不是實現化賦值,<constructor-arg value="yyyy年MM月dd hh時mm分ss秒"/>給當前bean進行例項化
這裡是Spring xml的Bean的配置,這樣很麻煩要自己手動去裝配,所以Spring 聲明瞭基於註解的方式去進行Bean的自動裝配
基於Annotation方式的Bean裝配:
在Spring中儘管使用XML配置檔案可以完成所有的配置工作,直觀表達Java EE程式設計師的"裝配意圖",但如果應用中Bean數量成千上萬的話,最終會導致XML配置檔案體積劇增,面對臃腫的XML配置檔案,給維護與升級帶來一定的困難。
偉大的Spring開發團隊想到了JDK 1.5提供的新特性--Annotation註釋技術:
瞭解了Annotation註釋的工作原理之後,方覺得真正偉大的不是Annotation註釋本身,而是幕後默默無聞地進行註釋處理的Annotation處理器
Annotation處理器是基於JDK的反射機制來實現的,Spring 2.5中定義的一系列Annotation註釋
Spring 2.5中常用的Annotation註釋說明:
@Autowired:通過@Autowired註解對Bean的屬性變數、屬性的Setter方法及建構函式進行標註,配合對應的註解處理器AutowiredAnnotationBeanProcessor完成Bean的自動配置工作。
@Autowired註解預設是按Bean型別進行裝配的,也就是說註解處理器AutowiredAnnotationBeanProcessor會在Spring容器中尋找與@Autowired註解所在屬性同類型的Bean例項進行裝配,如果找到多個滿足條件的Bean例項時,將會丟擲NoSuchBeanDefinitionException異常。
@Autowired註解加上@Qualifier註解的話,可以直接指定一個Bean例項名稱來進行裝配。
@Resource:@Resource的作用相當於@Autowired,配合對應的註解處理器CommonAnnotationBeanPostProcessor完成Bean的自動配置工作。
只不過@Autowired註解預設是按Bean型別進行裝配的,而@Resource註解預設是按Bean例項名稱進行裝配罷了
@Resource有兩個屬性是比較重要的,分別是name和type。Spring將@Resource註解的name屬性解析為Bean例項的名字,而type屬性則解析為Bean例項的型別
@Qualifier:如果@Autowired註解加上@Qualifier註解的話,可以將預設按Bean型別進行裝配變換為按Bean例項名稱進行裝配,具體的Bean例項名稱由@Qualifier註解的引數指定
@PostConstruct:在Bean中的某個方法上加上@PostConstruct註解,則該方法將會在Bean初始化之後被Spring容器呼叫,作用等同在Spring配置檔案中為bean標籤指定init-method屬性
@PreDestroy:在Bean中的某個方法上加上@PreDestroy註解,則該方法將會在Bean例項被銷燬之前由Spring容器進行呼叫,作用等同在Spring配置檔案中為bean標籤指定destroy-method屬性
在Java EE中啟用Spring的註解裝配通常需要經過以下幾個步驟。:
(1)匯入Spring註解裝配功能所依賴的JAR包Jcommon-annotations.jar,並將其加入到當前專案的classpath中來,該檔案在spring-framework-2.5.6\spring-framework-2.5.6 \lib\j2ee資料夾下可以找到
在Spring配置檔案中定義context名稱空間與相應的schemaLocation:
- <?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-2.5.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-2.5.xsd">
- </beans>
(3)在Spring配置檔案中開啟相應的註解處理器:
- <!-- 開啟註解處理器 -->
- <context:annotation-config/>
(4)在Bean中使用表6-4中列舉的Annotation註釋進行Bean屬性的自動裝配。
這個好處是使用了註解對bean的例項進行了自動裝配,不需要在建立bean例項中使用property標記進行物件的裝配,但必須要進行建立bean,要在xml中配置開啟註解處理器,才能使用註解的功能
http://www.springframework.org/schema/context-->註解裝配功能
<?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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 開啟註解出來器,這個spring檔案中所有的註解能進行使用 -->
<context:annotation-config/>
<!-- 通過構造方法注入屬性值裝配SimpleDateFormat單例項 建立bean-->
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
<!-- 建構函式賦值 -->
<constructor-arg value="yyyy年MM月dd hh時mm分ss秒"/>
</bean>
<!-- 建立date例項 -->
<bean id="now" class="java.util.Date"/>
<!-- 建立User例項 我們已經是使用了註解,所以不需要自動裝配 原型模式 每次呼叫時都會生成一個全新的User例項-->
<bean id="user" class="test.spring.bean.User" scope="prototype"/>
<!-- 建立 random 例項 單例-->
<bean id="random" class="java.util.Random"/>
<!-- 使用單例模式裝配XmlIocBean例項, 例項屬性通過Annotation註解方式注入 -->
<bean id="annotationIocBean" class="test.spring.bean.AnnotationIocBean" />
</beans>
因為這裡沒有使用註解掃描,所有要使用的類都要在這裡使用bean來建立例項化,
這裡只使用了開啟註解處理器,用到了自動裝配的功能。
這裡就是全部的Spring Bean的裝配的方式,這應該就是Spring IOC和DI的實現方式,所以bean的建立教給Spring,要使用就去拿就行了,不的不說Spring還是很強大的