2.Spring的Bean生命週期和組裝方式
1.Spring IoC容器概述
Spring IoC容器:
Spring容器即體現了IoC原理
Spring容器通過讀取配置元資料負責對Beans例項化、配置和裝配
配置元資料可以用XML、Java註解或Java程式碼來描述
org.springframework.beans和org.springframework.context包是Spring框架IoC容器的基礎
BeanFactory:
BeanFactory提供了一個先進的配置機制能夠管理任何型別的物件
BeanFactory負責對Bean物件的例項化、裝配和生命週期的管理
BeanFactory的實現:
XmlBeanFactory
建立該工廠需要傳入一個Resource例項,例如ClassPathResource或者FileSystemResource等
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
從BeanFactory獲取Bean例項
MyBean bean = (MyBean)factory.getBean("myBean")
ApplicationContext:
ApplicationContext是BeanFactory的一個子介面
ApplicationContext添加了更多的企業特定的功能:
例如增加了更方便的整合Spring的AOP功能
訊息資源處理(用於國際化)
事件的釋出
ApplicationContext的實現:
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
XmlWebApplicationContext
AnnotationConfigApplicationContext
兩者區別:
BeanFactory提供了配置框架和基本功能,ApplicationContext則添加了更多的企業特定功能
ApplicationContext是BeanFactory的一個子介面,同時也是它的一個完整的超集
例項Bean的載入方式不同:
BeanFactory延遲載入所有Bean,直到getBean()方法呼叫時才被建立
ApplicationContext啟動後載入所有單例項Bean。通過預載入單例項Bean,確保當需要時可以使用。
Spring IoC容器:
Spring IoC容器的使用:
配置元資料
基於Xml的配置
基於Annotation的配置
基於Java的配置
例項化容器
使用容器
2.Bean的概述
Bean概念;
一個Spring IoC容器管理了一個或者多個beans
這些beans通過你提供給容器的配置元資料進行建立
Bean的例項化:
通過構造方法例項化
使用靜態工廠方法例項化
使用例項工廠方法例項化
例項化Bean:
1.通過構造方法例項化:
當使用基於XML的元資料配置檔案,可以這樣來指定bean類:
2.使用靜態工廠方法例項化:
當採用靜態工廠方法建立bean時,除了需要指定class屬性外,還需要通過factory-method屬性來指定建立bean例項的工廠方法
注意,此定義並未指定返回物件的型別,僅指定該類包含的工廠方法,此例中createInstance方法必須是靜態的。
3.使用例項工廠方法例項化:
使用例項工廠方法例項化:
使用這種方式時,class屬性必須為空,而factory-bean屬性必須指定為當前(或其祖先)容器中包含工廠方法的bean的名稱
bean的工廠方法必須通過factory-method屬性來設定
Bean的宣告週期:
Bean作用域:
注意事項:
單例作用域是針對一個Spring容器一個例項,並且是Spring中Bean的預設作用域
Spring不會管理原型作用域的完整生命週期,他只負責初始化、 配置,亦或者組裝原型域的Bean物件,但是不會呼叫Bean的銷燬方法
3.Bean的依賴注入
依賴注入指物件之間的依賴關係
Spring容器的工作就是建立Bean並注入他所依賴的Bean物件
Spring中的注入方式主要有2種:構造器注入和Setter方法注入
構造器注入:
基於構造器注入DI通過呼叫帶引數的構造器來實現,每個引數代表著一個依賴關係
構造器引數通過引數型別進行匹配
我們還可以使用type屬性指定構造引數的型別
我們還可以使用index屬性指定構造引數的索引
我們還可以使用name屬性制定構造引數的名字
Setter注入
基本Bean注入
注入基本資料型別
<property name="xxx" value="xxx" />
可注入:
字串
數值型資料
布林型別
Spring根據欄位屬性來決定轉換成正確的型別
注入Null
<property name="xxx"><null /></property>
注入引用資料型別
引用
<property name="xxx" ref="xxxBean" />
<property name="xxx"> <ref bean="xxxBean" /></property>
注入內部Bean
<property name="xxx"> <bean class="org.xxx.XxxBean" /></property>
內部Bean不能複用,只能被注入
注入List型別和陣列型別
對應的Java型別是:List和Array
<property name=“xxx”> <list> <ref bean=“aa” /> <ref bean=“bb” /> <value>aaa</value> <value>bbb</value> </list></property>
注入List型別和陣列型別
對應的Java型別是:List和Array
<property name=“xxx”> <list> <ref bean=“aa” /> <ref bean=“bb” /> <value>aaa</value> <value>bbb</value> </list></property>
注入Set型別
對應的Java型別是:Set
<property name=“xxx”> <set> <ref bean =“aa” /> <ref bean =“bb” /> </set></property>
<set>保證其中每個元素都是唯一的
注入Map型別
對應的Java型別是:Map
<property name=“xxx”> <map> <entry key=“a” value-ref=“aa” /> <entry key=“b” value-ref=“bb” /> </map></property>
每個<entry>都有一個鍵和值組成
key: 指定map項的鍵為String
key-ref: 指定map項的鍵為Spring上下文中其他Bean的引用
value: 指定map項的值為String
value-ref: 指定map項的值為Spring上下文中其他Bean的引用
注入Properties型別
對應的Java型別是:Properties
<property name=“xxx”> <props> <prop key=“a”>aaa</prop> <prop key=“b”>bbb</prop> </props></property>
與Map唯一不同的是其限制了鍵和值都是String
高階Bean注入:
Spring容器可以自動裝配相互協作bean的關聯關係
自動裝配有以下好處:
自動裝配可以顯著得減少指定屬性或者構造器引數的需求
當物件發生變化時自動裝配可以更新配置而不需要修改配置
自動裝配的侷限性和缺點:
Property和constructor-arg顯示的依賴設定會覆蓋自動裝配(故意而為)
自動裝配沒有顯示編寫精確
在容器中可能存在多個bean的定義與自動裝配的setter方法或者構造方法引數匹配,若bean定義不唯一,裝配時會拋異常