1、構造器注入:java
1)常量值web
簡寫:<constructor-arg index="0" value="常量"/>spring
全寫:<constructor-arg index="0"><value>常量</value></constructor-arg>編程
2)引用數組
簡寫:<constructor-arg index="0" ref="引用"/>緩存
全寫:<constructor-arg index="0"><ref bean="引用"/></constructor-arg>session
2、setter注入: ui
1)常量值spa
簡寫:<property name="message" value="常量"/>prototype
全寫:<property name="message"><value>常量</value></ property>
2)引用
簡寫:<property name="message" ref="引用"/>
全寫:<property name="message"><ref bean="引用"/></ property>
3)數組:<array>沒有簡寫形式
4)列表:<list>沒有簡寫形式
5)集合:<set>沒有簡寫形式
6)字典
簡寫:<map>
<entry key="鍵常量" value="值常量"/>
<entry key-ref="鍵引用" value-ref="值引用"/>
</map>
全寫:<map>
<entry><key><value>鍵常量</value></key><value>值常量</value></entry>
<entry><key><ref bean="鍵引用"/></key><ref bean="值引用"/></entry>
</map>
7)Properties:沒有簡寫形式
使用p命名空間簡化setter注入:
<bean id="……" class="……" p:id="value"/> :常量setter注入方式,其等價於<property name="id" value="value"/>;
<bean id="……" class="……" p:id-ref="bean1"/> :引用setter注入方式,其等價於<property name="id" ref="bean1"/>。
4.傳統應用程序設計中所說的依賴通常指「類之間的關係」,那先讓咱們複習一下類之間的關係:
泛化:表示類與類之間的繼承關係、接口與接口之間的繼承關係;
實現:表示類對接口的實現;
依賴:當類與類之間有使用關係時就屬於依賴關係,不一樣於關聯關係,依賴不具備「擁有關係」,而是一種「相識關係」,只在某個特定地方(好比某個方法體內)纔有關係。
關聯:表示類與類或類與接口之間的依賴關係,表現爲「擁有關係」;具體到代碼能夠用實例變量來表示;
聚合:屬因而關聯的特殊狀況,體現部分-總體關係,是一種弱擁有關係;總體和部分能夠有不同的生命週期;是一種弱關聯;
組合:屬因而關聯的特殊狀況,也體現了體現部分-總體關係,是一種強「擁有關係」;總體與部分有相同的生命週期,是一種強關聯;
5.應用依賴注入能給咱們帶來哪些好處呢?
動態替換Bean依賴對象,程序更靈活:替換Bean依賴對象,無需修改源文件:應用依賴注入後,因爲能夠採用配置文件方式實現,從而能隨時動態的替換Bean的依賴對象,無需修改java源文件;
更好實踐面向接口編程,代碼更清晰:在Bean中只需指定依賴對象的接口,接口定義依賴對象完成的功能,經過容器注入依賴實現;
更好實踐優先使用對象組合,而不是類繼承:由於IoC容器採用注入依賴,也就是組合對象,從而更好的實踐對象組合。
增長Bean可複用性:依賴於對象組合,Bean更可複用且複用更簡單;
下降Bean之間耦合:因爲咱們徹底採用面向接口編程,在代碼中沒有直接引用Bean依賴實現,所有引用接口,並且不會出現顯示的建立依賴對象代碼,並且這些依賴是由容器來注入,很容易替換依賴實現類,從而下降Bean與依賴之間耦合;
代碼結構更清晰:要應用依賴注入,代碼結構要按照規約方式進行書寫,從而更好的應用一些最佳實踐,所以代碼結構更清晰。
<bean id="helloApi" class="cn.javass.spring.chapter2.helloworld.HelloImpl" lazy-init="true"/>
指指定Bean初始化及銷燬時的順序,使用depends-on屬性指定的Bean要先初始化完畢後才初始化當前Bean,因爲只有「singleton」Bean能被Spring管理銷燬,因此當指定的Bean都是「singleton」時,使用depends-on屬性指定的Bean要在指定的Bean以後銷燬。
那「depends-on」有什麼好處呢?主要是給出明確的初始化及銷燬順序,好比要初始化「decorator」時要確保「helloApi」Bean的資源準備好了,不然使用「decorator」時會看不到準備的資源;而在銷燬時要先在「decorator」Bean的把對「helloApi」資源的引用釋放掉才能銷燬「helloApi」,不然可能銷燬 「helloApi」時而「decorator」還保持着資源訪問,形成資源不能釋放或釋放錯誤。
bean中加
init-method="init" :指定初始化方法,在構造器注入和setter注入完畢後執行。
destroy-method="destroy":指定銷燬方法,只有「singleton」做用域能銷燬,「prototype」做用域的必定不能,其餘做用域不必定能;後邊再介紹。
經過設置Bean定義屬性autowire="byName",意思是根據名字進行自動裝配,只能用於setter注入。好比咱們有方法「setHelloApi」,則「byName」方式Spring容器將查找名字爲helloApi的Bean並注入,若是找不到指定的Bean,將什麼也不注入。
byType
經過設置Bean定義屬性autowire="byType",意思是指根據類型注入,用於setter注入,好比若是指定自動裝配方式爲「byType」,而「setHelloApi」方法須要注入HelloApi類型數據,則Spring容器將查找HelloApi類型數據,若是找到一個則注入該Bean,若是找不到將什麼也不注入,若是找到多個Bean將優先注入<bean>標籤「primary」屬性爲true的Bean,不然拋出異常來代表有個多個Bean發現但不知道使用哪一個。
bean中加dependency-check 用於檢查Bean定義的屬性都注入數據了,不論是自動裝配的仍是配置方式注入的都能檢查,若是沒有注入數據將報錯,從而提早發現注入錯誤,只檢查具備setter方法的屬性。
Spring3+也不推薦配置方式依賴檢查了,建議採用Java5+ @Required註解方式
「scope」,在面向對象程序設計中通常指對象或變量之間的可見範圍。而在Spring容器中是指其建立的Bean對象相對於其餘Bean對象的請求可見範圍。
Spring提供「singleton」和「prototype」兩種基本做用域,
另外提供「request」、「session」、「global session」三種web做用域;
Spring還容許用戶定製本身的做用域。
spring中對bean的管理和建立:
經過BeanDefinition類定義bean描述,記錄bean的Class,scope,惟一表示等。
BeanDifinitionRegister,緩存BeanDefinition。
singleton:在SingletonBeanRegister中使用註冊表方式,將bean id/name->SingletonBean作緩存,每次請求的時候從註冊表Map中獲取,有直接返回cache的Bean,沒就建立一個Singleton對象返回,並緩存。懶加載的是如上描述第一次請求時建立,其它的是初始化時建立。
prototype:在DefaultBeanFactory.getBean中,先從BeanDifinitionRegister獲取BeanDifinition,根據scope決定是new 個Bean仍是從SingletonBeanRegister獲取一個bean。