溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java程序員必須掌握的Spring依賴管理原理

發(fā)布時間:2020-07-31 06:42:40 來源:網(wǎng)絡 閱讀:882 作者:Java_老男孩 欄目:編程語言

Spring依賴注入

依賴注入(Dependency Injection)的意思就是對象通過構(gòu)造器函數(shù)參數(shù),工廠方法的參數(shù),或者成員屬性,定義了對象的依賴對象;容器在創(chuàng)建該對象時會負責注入這些依賴。這個過程是控制反轉(zhuǎn)的,即不是由即將創(chuàng)建的對象來管理自己的依賴的發(fā)現(xiàn)和實例化,而是有Spring容器來實現(xiàn)。

在Spring中依賴注入有兩種形式,第一種就是基于構(gòu)造函數(shù)的注入,即通過調(diào)用構(gòu)造函數(shù),傳入?yún)?shù),也就是依賴來完成整個依賴注入流程;第二種就是基于setter方法的注入。

構(gòu)造函數(shù)的參數(shù)的匹配,要避免歧義,如指定類型,指定參數(shù)的次序等。如果是按照參數(shù)名字匹配,則必須開啟debug模式進行編譯,否則參數(shù)名字是不保留的。如果不想開啟debug模式編譯,則可以使用@ConstructorProperties注解。
setter方法注入是先調(diào)用沒有參數(shù)的默認構(gòu)造函數(shù)構(gòu)建對象,或者沒有參數(shù)的靜態(tài)工廠方法,實例化bean后,調(diào)用setter方法來將該對象注入。

通過使用依賴注入,可以使代碼更簡潔,更好地實現(xiàn)對象之間解耦。另外,通過依賴注入管理的的對象是POJO類,可以更好地進行測試。

如何選擇合適的依賴注入方法?

最佳實踐是通過構(gòu)造器方法注入主要依賴對象,通過setter方法注入可選的依賴對象。雖然可以在setter方法上加上@Required注解來實現(xiàn)主要依賴對象注入,但一般還是推薦使用構(gòu)造器注入必須的依賴。

使用構(gòu)造器注入,可以使得應用的組件作為不可變的對象,而且可以保證注入依賴是非null的。另外,構(gòu)造器注入返回的是一個完整的初始狀態(tài)的實例。但是,一般不推薦大量使用構(gòu)造方法注入,如果出現(xiàn)這種情況,則說明代碼需要重構(gòu)。

setter方法適合注入可選的依賴,這些依賴可能有默認值,而且在其他位置使用這些依賴時務必要進行null值檢查。使用setter方法的一個好處是可以修改或者重新配置,或者需要時再注入。如基于JMX MBean的管理。

Spring依賴解析流程

首先ApplicationContext會被創(chuàng)建和初始化,會加載包括描述所有bean的元數(shù)據(jù)。這些配置元數(shù)據(jù)可以通過XML,Java代碼或者注解來指定。

對于每一個bean,它的依賴表現(xiàn)形式是成員屬性,構(gòu)造器參數(shù),或者靜態(tài)工廠方法的參數(shù)。在bean真正創(chuàng)建時,Spring容器會提供這些依賴的對象。這些參數(shù)可能是需要設置的默認值,也可能是另外一個bean的引用。

Spring容器會驗證每個bean的配置信息。并且在bean真正創(chuàng)建時才設置設置屬性值或者參數(shù)值。
在Spring中,單例作用域的bean會提前初始化,在Spring容器創(chuàng)建時就進行了實例化。對于其他的作用域的bean,則只在需要時才進行創(chuàng)建。之所以單例作用域的bean會被提前初始化,主要是為了解決依賴檢查的問題,下文的循環(huán)依賴一節(jié)會詳細說明。

在Spring內(nèi)部會構(gòu)建一個創(chuàng)建bean的依賴圖,按照這依賴關(guān)系來創(chuàng)建Bean。

循環(huán)依賴解決

如果使用構(gòu)造函數(shù)注入,則不能有循環(huán)依賴的情況。如A構(gòu)造器依賴B,同時B也構(gòu)造器依賴A。Spring IoC容器會在運行時檢測到循環(huán)依賴,拋BeanCurrentlyInCreationException異常。一種解決辦法是通過setter方法來解決循環(huán)依賴的情況。

Spring會在容器加載時檢測配置問題,如引用不存在或者循環(huán)依賴。Spring會在必要時才解析依賴,即盡可能晚的來解析依賴關(guān)系。延遲解析依賴可能導致后期請求獲取對象時報錯,如拋出一個異常,如丟失指定對象或者屬性。這種配置的延遲的可見性導致的問題使得ApplicationContext的實現(xiàn)要求單例作用域的bean提前記性初始化。雖然會耗費內(nèi)存和時間,因為并不是按需創(chuàng)建這些單例作用域的bean,但是可以在ApplicationContext創(chuàng)建時就可以發(fā)現(xiàn)配置問題。

下文會介紹通過指定bean的可以通過配置來覆蓋默認的行為,使得單例作用域的bean也是延遲初始化。
如果沒有循環(huán)依賴存在,則在注入依賴對象時,這些依賴的對象就已經(jīng)初始化完成了。即如果A依賴B,則在A初始化時,B已經(jīng)初始化完成了。也就是說,Bean是在相關(guān)依賴設置完成,并且相關(guān)的生命周期方法調(diào)用完畢后,才算是完成了初始化。

bean的延遲初始化

默認情況下ApplicationContext是提前初始化單例作用域的bean,作為ApplicationContext初始化的一部分。這樣可以盡快的發(fā)現(xiàn)配置問題??梢酝ㄟ^指定bean的lazy-init="true",讓bean在需要時才被初始化。

自動注入依賴

在Spring中可以自動注入依賴,可以減少指定屬性或者構(gòu)造器參數(shù),還可以隨著配置對象的變化來更新注入的對象。
自動注入依賴的模式有:通過名稱注入,通過類型注入,和通過構(gòu)造器注入。

總結(jié)

本文總結(jié)了Spring中的依賴管理的基本原理和常見的問題,具體的依賴注入配置語法還需要參考Spring的官方文檔來進行。


文末彩蛋

針對于上面所涉及到的知識點我總結(jié)出了有1到5年開發(fā)經(jīng)驗的程序員在面試中涉及到的絕大部分架構(gòu)面試題及答案做成了文檔和架構(gòu)視頻資料免費分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并發(fā)等架構(gòu)技術(shù)資料),希望能幫助到您面試前的復習且找到一個好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時間來學習,也可以關(guān)注我一下以后會有更多干貨分享。

資料獲取方式 QQ群搜索“708-701-457” 即可免費領(lǐng)取

Java程序員必須掌握的Spring依賴管理原理
Java程序員必須掌握的Spring依賴管理原理
Java程序員必須掌握的Spring依賴管理原理

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI