使用lazyInit縮短Spring Boot啟動時間
雖然Spring Boot DevTools提供的快速重啟有助於庫類載入,但並不能解決Spring Boot應用啟動時間長的問題。在本文中,我們將看看如何使用SpringBoot的懶載入屬性提升我們應用程式的啟動時間。
起初,無論你選擇哪種嵌入式伺服器Tomcat或Jetty,全新輕裝上陣的Spring Boot Web應用都會快速啟動。隨著新功能和依賴項不斷加入,應用程變得越來越重,啟動時間也越來越長。從建立與資料庫的連線,透過網路從整合端點獲取資料,或從本地資源載入以及解析50兆位元組的XML檔案,你的應用在啟動後就非常繁忙,有時超過十幾分鍾或更長時間。
所有繁重工作在都放在啟動時完成,這樣應用在執行時能有很好的效能,使用者操作我們的應用時就無需停頓等待或遇到糟糕的效能,所有資源都已準備好並進行快取,因此在真正請求時可立即使用。
另一方面,作為開發人員,我們也不喜歡等待並浪費時間對啟動日誌進行非生產性檢查。這裡有一個簡單的解決方案可以應用於任何專案,以減輕一些等待啟動的痛苦並改善你的開發體驗。
想象一下,如果你有一個Spring bean來載入和快取某些資源的值,資源可能是遠端Web服務或需要對映到模型物件的本地CSV檔案的陣列,在生產環境中,在啟動時需要做這樣事情。
但是,如果你在本地執行應用程式,則很可能並不總是需要此資源,而只是在使用依賴於它的功能時才需要此資源。在下面的示例中,我們使用sleep()方法人為代表應用的緩慢啟動。
Spring Boot可以進行有助於相關針對專案的設定,包括最常見的預設設定和隨時可用的配置,這無疑是很棒的,因為它節省了寶貴的時間 然而,對於框架的新手來說,可能不熟悉這些配置。
你可能知道@SpringBootApplication本身並沒有做任何事情。它預設組合三個註釋@Configuration,@EnableAutoConfiguration和@ComponentScan,但是,並不是每個人都知道@ComponentScan註釋有一個特別有用的屬性: lazyInit。
LazyInit是一個布林標誌,指示容器在啟動時或第一次訪問容器時是否應該立即地建立所有發現的bean。預設情況下,該標誌設定為false,這在生產中很好,但在本地計算機上開發應用程式時不一定。
我們想要實現的是僅在本地開發環境中啟用bean延遲載入,並在生產環境實現立即初始化載入。
上面的示例提供了一個普通的Spring Boot主入口應用類,它包含一個靜態內部配置類,其中惰性初始化設定為true。該類使用@Profile進行註釋,以便僅在啟用本地配置檔案時才啟用它。
原理很簡單,如果啟用了本地配置檔案,則LocalConfig類中@ComponentScan中的lazyInit將覆蓋主類上@SpringBootApplication批註提供的預設值。如果取消啟用本地配置檔案,則忽略LocalConfig類並使用預設值。
最後,你需要啟用計算機上的本地配置檔案,有幾個選項可供選擇。最簡單的方法是在你的作業系統中永久設定spring.profiles.active環境變數,或者在每次啟動應用程式之前用你喜歡的IDE自動設定。在IntelliJ中,可以在專案主類的Run / Debug配置中指定它。
或者,如果你有一個用於本地開發的單獨Maven配置檔案,並且你使用Spring Boot Maven外掛來執行你的應用程式,則可以在pom.xml中配置活動配置檔案。
你可以在GitHub儲存庫中測試示例專案的功能。首先,執行沒有本地配置檔案的應用程式,以檢視是否執行了ResourceLoader類的初始化。然後設定配置檔案並重新啟動應用程式。
起初,無論你選擇哪種嵌入式伺服器Tomcat或Jetty,全新輕裝上陣的Spring Boot Web應用都會快速啟動。隨著新功能和依賴項不斷加入,應用程變得越來越重,啟動時間也越來越長。從建立與資料庫的連線,透過網路從整合端點獲取資料,或從本地資源載入以及解析50兆位元組的XML檔案,你的應用在啟動後就非常繁忙,有時超過十幾分鍾或更長時間。
所有繁重工作在都放在啟動時完成,這樣應用在執行時能有很好的效能,使用者操作我們的應用時就無需停頓等待或遇到糟糕的效能,所有資源都已準備好並進行快取,因此在真正請求時可立即使用。
另一方面,作為開發人員,我們也不喜歡等待並浪費時間對啟動日誌進行非生產性檢查。這裡有一個簡單的解決方案可以應用於任何專案,以減輕一些等待啟動的痛苦並改善你的開發體驗。
想象一下,如果你有一個Spring bean來載入和快取某些資源的值,資源可能是遠端Web服務或需要對映到模型物件的本地CSV檔案的陣列,在生產環境中,在啟動時需要做這樣事情。
但是,如果你在本地執行應用程式,則很可能並不總是需要此資源,而只是在使用依賴於它的功能時才需要此資源。在下面的示例中,我們使用sleep()方法人為代表應用的緩慢啟動。
@Component class ResourceLoader { private List<Term> resources; @PostConstruct void initHeavyLoading() throws InterruptedException { log.info("Loading start"); // time-consuming execution Thread.sleep(10_000); resources = loadResources(); log.info("Loading end"); } // … } <p class="indent"> |
Spring Boot可以進行有助於相關針對專案的設定,包括最常見的預設設定和隨時可用的配置,這無疑是很棒的,因為它節省了寶貴的時間 然而,對於框架的新手來說,可能不熟悉這些配置。
你可能知道@SpringBootApplication本身並沒有做任何事情。它預設組合三個註釋@Configuration,@EnableAutoConfiguration和@ComponentScan,但是,並不是每個人都知道@ComponentScan註釋有一個特別有用的屬性: lazyInit。
LazyInit是一個布林標誌,指示容器在啟動時或第一次訪問容器時是否應該立即地建立所有發現的bean。預設情況下,該標誌設定為false,這在生產中很好,但在本地計算機上開發應用程式時不一定。
我們想要實現的是僅在本地開發環境中啟用bean延遲載入,並在生產環境實現立即初始化載入。
@SpringBootApplication public class LazyApplication { public static void main(String[] args) { SpringApplication.run(LazyApplication.class, args); } @Configuration @Profile("local") @ComponentScan(lazyInit = true) static class LocalConfig { } } <p class="indent"> |
上面的示例提供了一個普通的Spring Boot主入口應用類,它包含一個靜態內部配置類,其中惰性初始化設定為true。該類使用@Profile進行註釋,以便僅在啟用本地配置檔案時才啟用它。
原理很簡單,如果啟用了本地配置檔案,則LocalConfig類中@ComponentScan中的lazyInit將覆蓋主類上@SpringBootApplication批註提供的預設值。如果取消啟用本地配置檔案,則忽略LocalConfig類並使用預設值。
最後,你需要啟用計算機上的本地配置檔案,有幾個選項可供選擇。最簡單的方法是在你的作業系統中永久設定spring.profiles.active環境變數,或者在每次啟動應用程式之前用你喜歡的IDE自動設定。在IntelliJ中,可以在專案主類的Run / Debug配置中指定它。
或者,如果你有一個用於本地開發的單獨Maven配置檔案,並且你使用Spring Boot Maven外掛來執行你的應用程式,則可以在pom.xml中配置活動配置檔案。
你可以在GitHub儲存庫中測試示例專案的功能。首先,執行沒有本地配置檔案的應用程式,以檢視是否執行了ResourceLoader類的初始化。然後設定配置檔案並重新啟動應用程式。
禁用所選bean的延遲初始化
儘管@ComponentScan(lazyInit = true)會影響所有已掃描的bean,但你可以僅針對所選元件覆蓋此行為並立即初始化它們。該@Lazy註釋具有幾個不同的用途,可以應用於互補的景或替代解決方案。如果你有興趣在提高你的Spring應用程式的啟動速度,你一定要熟悉與@Lazy註釋。
瞭解你的工具集
在你使用JRebel之類的商業執行時位元組程式碼操作工具之前,有必要驗證簡單的延遲初始化是否不足以在開發環境中提高工作舒適度。Spring是一個高度精心設計的框架,它仍在不斷髮展。毫不奇怪,不瞭解一些有用的功能是常有的事。
雖然有些人可能會認為對框架內部的熟悉與一般使用框架的想法相矛盾,但這篇文章表明,至少學習基礎知識可能是有益的。
Faster Spring Boot startup | Java & Web developmen
[該貼被banq於2018-08-19 08:50修改過]
相關文章
- Spring Boot 3用CDS提升20%啟動時間Spring Boot
- 微軟釋出Win10 Build 17120:WDAG啟動時間縮短微軟Win10UI
- 使用 Kotlin Symbol Processing 1.0 縮短 Kotlin 構建時間KotlinSymbol
- [maven][spring boot] mvn spring-boot:run啟動時,指定pom檔案MavenSpring Boot
- 延緩Spring Boot啟動時間直到資料庫啟動的方法和原始碼 - MartenSpring Boot資料庫原始碼
- spring-boot啟動Springboot
- Spring Boot啟動流程Spring Boot
- 使用Spring GraalVM Native外掛提高SpringBoot啟動時間94%LVMSpring Boot
- Spring Boot應用,使用native編譯與不使用的啟動時間和記憶體佔用對比Spring Boot編譯記憶體
- Spring Boot Starters啟動器Spring Boot
- Spring Boot Runner啟動器Spring Boot
- Spring Boot 啟動過程Spring Boot
- 使用 Spring Boot 3.2 和 CRaC 實現更快啟動Spring Boot
- Spring Boot(三):Spring Boot中的事件的使用 與Spring Boot啟動流程(Event 事件 和 Listeners監聽器)Spring Boot事件
- Spring Boot 2.0(七):Spring Boot 如何解決專案啟動時初始化資源Spring Boot
- Spring Boot啟動流程簡述Spring Boot
- Maven專案Spring Boot啟動MavenSpring Boot
- Spring Boot移除內嵌Tomcat,使用非web方式啟動Spring BootTomcatWeb
- 痞子衡嵌入式:在i.MXRT1xxx系列上用NAND型啟動裝置時可用兩級設計縮短啟動時間NaN
- 縮短 Linux 命令節省時間的四種方法Linux
- Spring Boot定製啟動圖案Spring Boot
- spring boot 啟動時報錯The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized orJDBC driverSpring BootServerZedJDBC
- 在Spring Boot應用啟動時如何執行程式碼? -DukesletterSpring Boot行程
- 啟動延時縮短 50%-80%,函式計算釋出映象加速功能函式
- 使用Lodash工具後程式碼行數瞬間縮短...
- 冷啟動延時縮短50%-80%,阿里雲函式計算釋出冷啟動加速技術阿里函式
- spring boot學習(4): 命令列啟動Spring Boot命令列
- Spring Boot原始碼分析-啟動過程Spring Boot原始碼
- Spring Boot 應用程式啟動流程分析Spring Boot
- Spring boot學習(一)開啟Spring boot之旅Spring Boot
- 如何用Spring Boot解決專案啟動時初始化資源?Spring Boot
- 在Spring Boot中建立自己的啟動器Spring Boot
- Spring Boot中Tomcat是怎麼啟動的Spring BootTomcat
- Spring Boot 系統啟動任務定義Spring Boot
- 一文了解Spring Boot啟動類SpringApplicationSpring BootAPP
- 加快Spring Boot啟動的幾種方法 | baeldungSpring Boot
- spring boot 不連線資料庫啟動Spring Boot資料庫
- 如何縮短開發直播間原始碼的時間,看懂這些就OK了原始碼