Spring系列第十二講 lazy-init:bean延遲初始化
bean實時初始化
在容器啟動過程中被建立組裝好的bean,稱為實時初始化的bean,spring中預設定義的bean都是實時初始化的bean,這些bean預設都是單例的,在容器啟動過程中會被建立好,然後放在spring容器中以供使用。
實時初始化bean的有一些優點
-
更早發下bean定義的錯誤:實時初始化的bean如果定義有問題,會在容器啟動過程中會丟擲異常,讓開發者快速發現問題
-
查詢bean更快:容器啟動完畢之後,實時初始化的bean已經完全建立好了,此時被快取在spring容器中,當我們需要使用的時候,容器直接返回就可以了,速度是非常快的。
案例
ActualTimeBean類
一會我們在spring中建立上面這個物件,建構函式中會輸出一段話,這段話會在spring容器建立過程中輸出。
actualTimeBean.xml
測試用例
注意上面程式碼,容器啟動前後有輸出,執行actualTimeBean輸出:
可以看出actualTimeBean這個bean是在容器啟動過程中被建立好的。
延遲初始化的bean
從上面我們可以看出,實時初始化的bean都會在容器啟動過程中建立好,如果程式中定義的bean非常多,並且有些bean建立的過程中比較耗時的時候,會導致系統消耗的資源比較多,並且會讓整個啟動時間比較長,這個我估計大家都是有感受的,使用spring開發的系統比較大的時候,整個系統啟動耗時是比較長的,基本上多數時間都是在建立和組裝bean。
spring對這些問題也提供瞭解決方案:bean延遲初始化。
所謂延遲初始化,就是和實時初始化剛好相反,延遲初始化的bean在容器啟動過程中不會建立,而是需要使用的時候才會去建立,先說一下bean什麼時候會被使用:
-
被其他bean作為依賴進行注入的時候,比如透過property元素的ref屬性進行引用,透過構造器注入、透過set注入、透過自動注入,這些都會導致被依賴bean的建立
-
開發者自己寫程式碼向容器中查詢bean的時候,如呼叫容器的getBean方法獲取bean。
上面這2種情況會導致延遲初始化的bean被建立。
延遲bean的配置
在bean定義的時候透過lazy-init屬性來配置bean是否是延遲載入,true:延遲初始化,false:實時初始化
我們來2個案例看一下效果。
LazyInitBean類
lazyInitBean.xml
注意上面的lazy-init="true"表示定義的這個bean是延遲初始化的bean。
測試用例
LazyBeanTest中加個方法
注意上面的輸出,容器啟動前後有輸出,然後又從容器中查詢LazyInitBean。
執行輸出
執行lazyInitBean方法,輸出:
程式碼結合輸出可以看出來,LazyInitBean在容器啟動過程中並沒有建立,當我們呼叫context.getBean方法的時候,LazyInitBean才被建立的。
案例2
上面這種方式是我們主動從容器中獲取bean的時候,延遲初始化的bean才被容器建立的,下面我們再來看一下當延遲初始化的bean被其他實時初始化的bean依賴的時候,是什麼時候建立的。
ActualTimeDependencyLazyBean類
ActualTimeDependencyLazyBean類中有個lazyInitBean屬性,對應的有get和set方法,我們將透過set方法將lazyInitBean物件注入。
actualTimeDependencyLazyBean.xml
注意上面定義了2個bean:
lazyInitBean:lazy-init為true,說明這個bean是延遲建立的
actualTimeDependencyLazyBean:透過property元素來注入lazyInitBean,actualTimeDependencyLazyBean中沒有指定lazy-init,預設為false,表示是實時建立的bean,會在容器建立過程中被初始化
測試用例
LazyBeanTest中加個方法,如下:
執行輸出
從容器中可以看到,xml中定義的2個bean都在容器啟動過程中被建立好了。
有些朋友比較迷茫,lazyInitBean的lazy-init為true,怎麼也在容器啟動過程中被建立呢?
由於actualTimeDependencyLazyBean為實時初始化的bean,而這個bean在建立過程中需要用到lazyInitBean,此時容器會去查詢lazyInitBean這個bean,然後會進行初始化,所以這2個bean都在容器啟動過程中被建立的。
總結 gansu/
延遲初始化的bean無法在程式啟動過程中迅速發現bean定義的問題,第一次獲取的時候可能耗時會比較長。在實際工作中用的比較少,作為了解,以後碰到的時候會有個印象。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30239065/viewspace-2731545/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- spring的延遲初始化bean (default-lazy-init 與 lazy-init )SpringBean
- Spring Boot 2.2中的延遲初始化Spring Boot
- 【spring原始碼系列】之【Bean的初始化】Spring原始碼Bean
- Spring IoC bean 的初始化SpringBean
- Spring Bean如何初始化的SpringBean
- Spring系列第四講 xml中bean定義詳解SpringXMLBean
- Spring系列第十四講 單例bean中使用多例bean,你未必會玩?Spring單例Bean
- Spring容器 —— 深入 bean 的載入(五、初始化 bean)SpringBean
- Spring系列第六講 玩轉bean scope,避免跳坑裡!SpringBean
- 一不小心,你就掉進了Spring延遲初始化的坑!Spring
- Spring Boot(十四)RabbitMQ延遲佇列Spring BootMQ佇列
- Spring系列.Bean簡介SpringBean
- Spring 原始碼(17)Spring Bean的建立過程(8)Bean的初始化Spring原始碼Bean
- Spring Boot 2.2 中的延遲載入Spring Boot
- 【JVM系列】低延遲迴收器 ZGCJVMGC
- Spring系列第十三講 使用繼承簡化bean配置(abstract & parent)Spring繼承Bean
- RocketMQ系列(五)廣播與延遲訊息MQ
- Spring系列第五講 建立bean例項這些方式你們都知道?SpringBean
- 從原理分析Kotlin的延遲初始化: lateinit var和by lazyKotlin
- 4_Spring Bean的初始化和銷燬SpringBean
- Spring系列第十一講 bean中的autowire-candidate又是幹什麼的?SpringBean
- spring原始碼深度解析— IOC 之 bean 的初始化Spring原始碼Bean
- RabbitMQ延遲訊息的延遲極限是多少?MQ
- 延遲繫結
- SpringCloud 2020.0.4 系列之 Stream 延遲訊息 的實現SpringGCCloud
- spring-IOC容器原始碼分析(一)bean初始化流程Spring原始碼Bean
- spring原始碼之bean的初始化及迴圈引用Spring原始碼Bean
- 【spring原始碼系列】之【Bean的銷燬】Spring原始碼Bean
- 探索Spring系列(一)Spring容器和Bean的生命週期SpringBean
- redis 延遲佇列Redis佇列
- Mybatis延遲查詢MyBatis
- WebGL之延遲著色Web
- Laravel 延遲佇列Laravel佇列
- 疫情延遲 題解
- 實現簡單延遲佇列和分散式延遲佇列佇列分散式
- 基於rabbitmq延遲外掛實現分散式延遲任務MQ分散式
- 【spring原始碼系列】之【Bean的生命週期】Spring原始碼Bean
- Spring原始碼分析之 lazy-init 實現原理Spring原始碼