前言
在一個名為種花家的小鎮上,生活着一群熱愛程式設計的人。他們緻力于建構出高效、可維護的軟體系統,而 Spring Boot 架構成為了他們的不二之選。這個小鎮上的人們每天都在用 Spring Boot 架構創造着令人矚目的應用程式。
然而,随着時間的推移,他們的應用程式變得越來越龐大,包含了許多不同的子產品群組件。在應用程式啟動的時候,所有的 bean 都會被一次性初始化,這導緻了一個令人頭疼的問題:啟動時間變得越來越長了。
小鎮的居民們開始感到困擾。他們意識到,無論是在開發環境還是在生産環境中,啟動時間的長短都直接關系到他們的工作效率和使用者體驗。于是,他們尋找一種解決方案,希望能夠在保證應用程式正常運作的同時,減少啟動時間的開銷。
正當大家糾結不已時,一個程式設計少俠出現了。他名叫不一樣的科技宅,他告訴大家,有一種叫做"延遲初始化"的政策,可以幫助他們解決這個問題。
據說,延遲初始化能夠将 bean 的初始化推遲到第一次使用時進行,而不是在應用程式啟動時立即初始化。這樣一來,隻有當某個 bean 真正被需要時,才會進行初始化,避免了不必要的資源消耗和時間開銷。
是什麼?
延遲初始化(Lazy Initialization)是一種在需要時才建立或加載對象的政策,以減少啟動時間和資源消耗。在 Spring 中,延遲初始化允許将 Bean 的建立推遲到第一次通路該 Bean 時才進行,而不是在應用程式啟動時立即建立。
有啥用?
節省資源
當應用程式中存在大量的 bean 時,立即初始化所有 bean 可能會占用大量的記憶體和處理時間。通過延遲初始化,隻有在需要使用 bean 時才會進行初始化,可以避免不必要的資源消耗。
加快啟動時間
延遲初始化可以減少應用程式啟動時間,因為隻有在需要時才會加載和初始化 bean。對于那些在應用程式啟動時可能不會使用的較大或複雜的 bean,延遲初始化可以顯著加快啟動時間。
解決循環依賴
Spring 容器可以管理 bean 之間的依賴關系。當存在循環依賴時,延遲初始化可以幫助解決這個問題。通過延遲初始化,Spring 容器可以在運作時逐個解析和滿足 bean 之間的依賴,而不是在初始化階段發現無法解決的循環依賴。
如何實作?
Spring Boot 中實作延遲初始化 Bean,可以采取以下四種方法:
- 對于使用注解配置的 Bean,可以在 Bean 的定義上使用 @Lazy 注解來實作延遲初始化。
示例:
@Lazy
@Component
public class MyBean {
// Bean 的定義
}
- 對于使用 Java 配置類的方式,可以在 @Bean 注解上使用 @Lazy 注解,以實作延遲初始化。
示例:
@Configuration
public class AppConfig {
@Lazy
@Bean
public MyBean myBean() {
// Bean 的定義
return new MyBean();
}
}
- 對于 XML 配置的 Bean,可以在 <bean> 元素上設定 lazy-init 屬性為 true,以實作延遲初始化。
示例:
<bean id="myBean" class="com.example.MyBean" lazy-init="true" />
- 對于使用@ComponentScan注解,可以配置屬性lazyInit = true 實作某些包下面所有的 bean 延遲初始化。
示例:
package com.example.demo.bean;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
public MyBean() {
System.out.println("My bean init success.");
}
}
@SpringBootApplication
@ComponentScan(value = "com.example.demo.bean", lazyInit = true)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
全局懶加載
上面示範案例,意味着我們隻能對自己實作的 bean 進配置。但是項目中肯定會引入很多第三方的 starter,比如 redis,mq。如果想對引入的第三方庫進行配置,那就不太容易了,是以我們可以開啟全局懶加載。
配置檔案增加下面的配置:
spring:
main:
lazy-initialization: true #預設false 關閉
開啟了全局懶加載,想要過濾某個 bean,可以通過設定 @Lazy(false) 排除。
@Component
@Lazy(false)
public class MyBean {
public MyBean() {
System.out.println("My bean init success.");
}
}
還有一種是通過配置 LazyInitializationExcludeFilter 規則實作排除。
@Configuration
public class AppConfig {
@Bean
LazyInitializationExcludeFilter integrationLazyInitExcludeFilter() {
return LazyInitializationExcludeFilter.forBeanTypes(MyBean.class);
}
}
注意的點
@Lazy 注解的使用
要確定在正确的位置使用@Lazy 注解。通常情況下,将其添加在 Bean 的定義上,例如@Component、@Service、@Repository 等注解上。這樣可以確定被标記的 Bean 在第一次使用時才會進行初始化。
依賴關系的處理
懶加載的 Bean 可能會被其他 Bean 所依賴。在處理依賴關系時,要確定依賴的 Bean 已經被初始化或者也進行了懶加載。否則,可能會導緻依賴注入失敗或出現異常。
延遲初始化帶來的影響
懶加載雖然可以提高應用的啟動性能,但也會帶來一些影響。由于 Bean 的初始化被延遲到第一次使用,是以在初始化時可能會出現較長的延遲,對于需要立即使用的 Bean 可能會造成一定的等待時間。
記憶體消耗的控制
懶加載雖然可以減少應用啟動時的記憶體消耗,但也需要注意對記憶體的控制。如果應用中存在大量的懶加載 Bean,并且這些 Bean 在實際使用中并不頻繁,可能會導緻過多的記憶體占用。是以,需要根據應用的具體情況,合理使用懶加載,避免過度消耗記憶體。
運作時異常的處理
由于懶加載将 Bean 的初始化延遲到運作時,是以在初始化過程中可能會發生異常。要確定适當地處理這些異常,以防止應用的崩潰或不可預料的行為。
總結
懶加載是一種延遲加載的技術,用于在需要時才加載資源,而不是在應用啟動時加載所有資源。在 Spring Boot 架構中,有兩種方式可以實作懶加載:Spring 懶加載和全局懶加載。無論是懶加載還是全局懶加載,它們都能提升應用的性能和效率,避免不必要的資源加載。
在使用 Spring 懶加載需要注意正确的注解使用、處理依賴關系、延遲初始化帶來的影響、記憶體消耗控制和異常處理等方面。合理地使用可以提高應用性能,但也需要綜合考慮應用的需求和場景,以確定有效性和穩定性。
結尾
如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的首頁看看,說不定有你喜歡的文章,也可以随手點個關注哦,謝謝。
我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活。我們下期見!