依賴注入(Dependency Injection
)的意思就是對象經過構造器函數參數,工廠方法的參數,或者成員屬性,定義了對象的依賴對象;容器在建立該對象時會負責注入這些依賴。這個過程是控制反轉的,即不是由即將建立的對象來管理本身的依賴的發現和實例化,而是有Spring容器來實現。html
在Spring
中依賴注入有兩種形式,第一種就是基於構造函數的注入,即經過調用構造函數,傳入參數,也就是依賴來完成整個依賴注入流程;第二種就是基於setter
方法的注入。spring
構造函數的參數的匹配,要避免歧義,如指定類型,指定參數的次序等。若是是按照參數名字匹配,則必須開啓debug
模式進行編譯,不然參數名字是不保留的。若是不想開啓debug
模式編譯,則可使用@ConstructorProperties
註解。函數
setter
方法注入是先調用沒有參數的默認構造函數構建對象,或者沒有參數的靜態工廠方法,實例化bean
後,調用setter
方法來將該對象注入。測試
經過使用依賴注入,可使代碼更簡潔,更好地實現對象之間解耦。另外,經過依賴注入管理的的對象是POJO
類,能夠更好地進行測試。ui
最佳實踐是經過構造器方法注入主要依賴對象,經過setter
方法注入可選的依賴對象。雖然能夠在setter
方法上加上@Required
註解來實現主要依賴對象注入,但通常仍是推薦使用構造器注入必須的依賴。debug
使用構造器注入,可使得應用的組件做爲不可變的對象,並且能夠保證注入依賴是非null
的。另外,構造器注入返回的是一個完整的初始狀態的實例。可是,通常不推薦大量使用構造方法注入,若是出現這種狀況,則說明代碼須要重構。code
setter
方法適合注入可選的依賴,這些依賴可能有默認值,並且在其餘位置使用這些依賴時務必要進行null
值檢查。使用setter
方法的一個好處是能夠修改或者從新配置,或者須要時再注入。如基於JMX MBean
的管理。htm
首先ApplicationContext
會被建立和初始化,會加載包括描述全部bean
的元數據。這些配置元數據能夠經過XML
,Java
代碼或者註解來指定。對象
對於每個bean
,它的依賴表現形式是成員屬性,構造器參數,或者靜態工廠方法的參數。在bean
真正建立時,Spring
容器會提供這些依賴的對象。這些參數多是須要設置的默認值,也多是另一個bean
的引用。生命週期
Spring
容器會驗證每一個bean
的配置信息。而且在bean
真正建立時才設置設置屬性值或者參數值。
在Spring
中,單例做用域的bean
會提早初始化,在Spring
容器建立時就進行了實例化。對於其餘的做用域的bean
,則只在須要時才進行建立。之因此單例做用域的bean
會被提早初始化,主要是爲了解決依賴檢查的問題,下文的循環依賴一節會詳細說明。
在Spring
內部會構建一個建立bean
的依賴圖,按照這依賴關係來建立Bean
。
若是使用構造函數注入,則不能有循環依賴的狀況。如A
構造器依賴B
,同時B
也構造器依賴A
。Spring IoC
容器會在運行時檢測到循環依賴,拋BeanCurrentlyInCreationException
異常。一種解決辦法是經過setter
方法來解決循環依賴的狀況。
Spring
會在容器加載時檢測配置問題,如引用不存在或者循環依賴。Spring
會在必要時才解析依賴,即儘量晚的來解析依賴關係。延遲解析依賴可能致使後期請求獲取對象時報錯,如拋出一個異常,如丟失指定對象或者屬性。這種配置的延遲的可見性致使的問題使得ApplicationContext
的實現要求單例做用域的bean
提早記性初始化。雖然會耗費內存和時間,由於並非按需建立這些單例做用域的bean
,可是能夠在ApplicationContext
建立時就能夠發現配置問題。
下文會介紹經過指定bean
的能夠經過配置來覆蓋默認的行爲,使得單例做用域的bean
也是延遲初始化。
若是沒有循環依賴存在,則在注入依賴對象時,這些依賴的對象就已經初始化完成了。即若是A
依賴B
,則在A
初始化時,B
已經初始化完成了。也就是說,Bean
是在相關依賴設置完成,而且相關的生命週期方法調用完畢後,纔算是完成了初始化。
默認狀況下ApplicationContext
是提早初始化單例做用域的bean
,做爲ApplicationContext
初始化的一部分。這樣能夠儘快的發現配置問題。能夠經過指定bean
的lazy-init="true"
,讓bean
在須要時才被初始化。
在Spring中能夠自動注入依賴,能夠減小指定屬性或者構造器參數,還能夠隨着配置對象的變化來更新注入的對象。
自動注入依賴的模式有:經過名稱注入,經過類型注入,和經過構造器注入。
本文總結了Spring
中的依賴管理的基本原理和常見的問題,具體的依賴注入配置語法還須要參考Spring
的官方文檔來進行。