spring容器&classLoader


spring通過一個容器的概念,引入父子容器結構,實現bean的隔離&繼承結構。

這種模式在很多場合都有類似的設計,比如Java的classloader機制,OSGi的bundle機制等。

這種機制的優勢,在於將對象的作用范圍進行約束。在復雜環境下,可以通過限定作用范圍使得有沖突的內容和諧共存。

接下來從多個角度闡述對比這幾個方面共同點&差異之處。

  • 隔離

spring通過容器的繼承關系,結合尋找bean的方式實現這個隔離性。在尋找bean時,是先從當前容器尋找,找不到再從父容器中尋找,然后逐層往上尋找直至找到或者到最頂層。

一般常用的容器類有,BeanFactory,AnnotationConfigApplicationContext。

 

Jvm的classloader一般有3級,且按順序進行加載。分別是:

    •   Bootstrap Classloader

加載核心類庫,比如rt.jar, resources.jar等。

    •   Extention Classloader

加載擴展目錄下的jar包與class。

    •   AppClassloader

加載當前應用classpath下的所有類。

這個多級classloader和父子容器的概念非常相似,父層級在子層級之前初始化,尋找資源時,優先從子層級的緩存開始,然后逐層往上委派,然后再從上往下尋找下來。

 

  

OSGi則在這個概念上更進一步,其bundle是一個獨立的classloader,其賦予這個classloader上承載的bundle有動態裝載卸載的能力,進而賦予業務動態更新業務邏輯的能力。其通過導入導出package控制邏輯可見性,通過classloader的委派加載模式進行業務class的JVM內共享。

這種模式在目前的微服務體系下,顯得過於復雜。但是其思想還是可以學習的,動態能力在jvm內容易出一些資源,可見性,穩定性等問題,這些問題很難有合適的解決方案;在jvm外則就是一致性與可靠性相關的問題,這些問題相對有合適的解決方案,擴展性也更佳。

  • 繼承

spring多級容器嵌套繼承后,尋找bean時,可優先從當前容器尋找,找不到再逐層上升到父容器尋找。

jvm的classloader也有繼承結構,appclassloader的父默認就是extClassloader,默認創建的classloader的父都是appClassloader。加載class時,會基於雙親委托的模式進行尋找。先查看當前classloader的緩存是否有,沒有則委托父classloader進行加載,然后遞歸這個流程往上到bootstrap classloader,如果找到了,直接返回,如果沒找到,則折返一級一級往下,在每一層級的掃描范圍內進行加載,直到找到或者找不到為止。

OSGi則是在當前bundle所在的classloader中尋找,找不到再根據package從classloader注冊中心篩選出注冊這個package的classloader對應的bundle。然后再委派這個bundle加載這個class。

  • 運行期動態能力

spring的bean一般啟動時就初始化完成了,基本不會搞運行期動態注冊的事情,畢竟IOC已經處理完成的事情,沒辦法再次注入,需要動態能力的都會走其他方式,比如腳本語言,配置中心等。

但是,可以基於BeanFactory的生命周期管理,動態維護一個Spring容器,基於這個容器實現動態能力。這個就有點類似OSGi,但是因為不涉及跨classloader,復雜度能低很多。

classLoader允許運行期動態裝卸載class,一般在動態代理,動態腳本更新等場合用的比較多。

OSGi,按bundle更新的,這個可以做到隨時更新,但是設計&開發的復雜度很高,使用比較復雜,用好很難。

 

參考資料:https://blog.csdn.net/briblue/article/details/54973413


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM