一、BeanFactory介紹
1.1、Bean:
- 在Spring技術中是基於組件的
- 最基本了是最常用的單元
- 其實實例保存在Spring的容器當中
Bean通常被定義在配置文件當中,Bean實例化由Spring的Ioc容器進行管理,Bean的實例可以通過Beanfactory進行訪問,實際上大部分J2EE應用,Bean是通過ApplicationContext來訪問的,ApplicationContext是BeanFactory的子接口,功能要比BeanFactory強大許多
1.2、BeanFactory作用
- 配置、創建以及管理Bean對象
- 維持Bean對象之間的依賴關系
- 負責Bean對象的生命周期
BeanFactory常用方法:
- containsBean(String beanname)
- Object getBean(String beanName)
通常使用XmlBeanFactory類來實現
1.3、ApplicationContext
- 讀取Bean定義文件
- 維護Bean之間的依賴關系
- 國際化的支持
- 資源文件的讀取getRource()方法可以輕松讀取Rource對象
- 事件傳播
- 多配置文件加載
二、Bean定義
2.1、基本組成
配置文件
- <beans/>是Sring配置文件的根節點
- 一個<beans/>節點里面可以有多個<bean>節點
定義<bean>節點時,通常要指定兩個屬性
id:用來指明bean的標識符,這個標識符具有唯一性,Spring對bean的管理以及bean之間這種依賴關系都需要這個屬性
class: 指明該bean的具體實現類,這里不能是接口(可以是接口實現類)全路徑包名.類名
Bean在Spring容器中兩種行為(通過scope來設置默認不寫為singelton)
singleton:單實例模式(默認,構造方法為private),整個Spring的容器中只有一個共享實例存在(singleton)
non-singelton:每次請求該bean,Spring容器都會新建立一個bean實例,然后返回給程序(request,session,prototype)
2.2、創建Bean
Bean的命名:
按照Java中的命名規范即可,使用清晰的,描述性的,一致的命名規范
Bean的命名機制:
id 當在Spring的窗口當中,查找某個Bean對象時,首先根據id進行查找,將其余作為Bean的默認名稱,如果ID屬性不存在,則根據Name屬性進行查找(將其中的第一個名稱作為默認的名稱),如果ID和NAME都不存在根據類的名稱進行查找
id---------->name--------------->類名
<bean id="id1" class="實現類"></bean> <bean name="id1" class="實現類"></bean> <bean class="實現類"></bean>
Bean的別名:
通過alias屬性指定:
<alias name="指定關聯的Bean的名稱fromname" alias="該關聯類的別名的名稱toname"/>
2.3、創建Bean步驟
創建XML文件----寫入配置信息---生成Bean類----加入Bean到配置文件
三、Bean注入
3.1、基本類型和String
- 用到Value元素
- XML解析器以String類型解析出數據
如果屬性不是String類型,屬性值會通過PropertyEditors轉換為其他類型
3.2、注入Bean
-ref元素進行標識
Ref元素通常有兩個屬性:
bean:指定不在同一個XML文件中的bean的id
<bean id="test" class="com.pb.test"> <property name="user"> <ref bean="其他的bean的id"/> </property> </bean>
local:指定在同一個XML文件中的bean的id
<bean id="test" class="com.pb.test"> <property name="user"> <ref bean="相同的XML文件中的bean的id"/> </property> </bean>
value和ref的區別:
使用ref元素,可以讓Spring在部署時驗證依賴的Bean是否真實存在
使用value元素,進行指定僅在創建Bean實例時做驗證,會導致錯誤的延時出現,而且還會帶來額外的類型轉制開銷
3.3、集合注入
List:
<bean id="test" class="com.pb.test"> <property name="lists"> <list> <value>1</value> <value>2</value> <value>3</value> </list> </property> </bean>
Map:
<bean id="test" class="com.pb.test"> <property name="map"> <map> <entry key="key1"> <value>value1</value> </entry> <entry key="key2"> <value>key2</value> </entry> </map> </property> </bean>
props:
<bean id="test" class="com.pb.test"> <property name="props"> <props> <prop key="key1">value1</prop> <prop key="key2">value2</prop> </props> </property> </bean>
set:
< property name ="interest" > < set > < value > 唱歌 </ value > < value > 跳舞 </ value > < value > 書法 </ value > </ set > </ property >
3.4、自動綁定
通過autowire屬性來設置
no:默認的。默認為不綁定
byName:根據屬性名稱自動進行綁定
byType:根據屬性類型自動進行綁定
四、Bean的作用域
- singleton:(單實例模式)spring容器只會存在一個共享的bean實例,並且所有針對該bean的請求只會返回同一個bean實例。
- propertype(no-singleton):對每一次針對該bean的請求都會生成一個新的bean實例。 相當於java中的new 操作。定義為propertype的bean其生命周期很長,不易回收,通常要額外的處理。
- request:針對每一次的http請求都會產生一個新的bean實例,Bean僅在當前的http request范圍內有效
- session:針對每一次的http請求都會產生一個新的bean實例,Bean僅在當前的http session范圍內有效
五、Bean管理生命周期
5.1、Bean的生命周期
5.2、生命周期管理
兩個時機
Spring可以管理實例化bean之間以及銷毀之前的行為
注入依賴關系之后:
- 使用init-method屬性:通過指定init-method屬性,確定某個方法應該在Bean依賴關系結束之后執行。這種方式無需要將代碼與Spring的接口耦合在一起代碼污染極小。通常在bean當中進行方法定義如init()方法,然后在配置文件Bean元素中加入init-method屬性來實現這個過程。
- 實現InnitializingBean接口:這種方式無須指明init-method屬性,當窗口依賴注入以后,會自動調用afterPropertiesSet方法,它和init-method執行效果一樣,但這種方式屬於侵入性的代碼設計不推薦使用
銷毀Bean之前:
- destroy-method:用於在執行Bean銷毀之前所執行的方法,這種方式和init-method一樣無壓需要代碼與Spring的接口耦合在一起代碼污染極小。在bean中加入destory-method屬性和實現這個過程
- 實現DisposeableBean接口:無需要指明destory-method屬性,當容器依賴注入以后,會自動調用destroty方法,屬於侵入性代碼設計不推薦使用
六、Bean的繼承
Bean的繼承:
什么是Bean繼承呢?繼承是指子bean可以從父bean繼承配置信息,也可以覆蓋特定的配置信息,或者在父bean的基礎之上加入新的配置信息,其實質類似於java中的子類與父類的繼承關系,利用繼承可以節省很多配置工作,在實際的項目應用中,共有的配置會配置成模板,供子bean繼承,如果2個bean之間配置信息大致相同,可以采用bean的繼承來減少配置工作。
Bean的模板:
在Spring中既然要將公用的配置,配置稱模板,這個模板不需要被實例化,而僅僅作為子bean的模板來使用,但在ApplicationContext或者BeanFactory默認會初始化所有的bean.
使用abstract屬性,該屬性可以阻止模板被實例化
abstract="true"時,表示該bean是抽象的bean,不能被初始化。