隨着咱們項目的不斷迭代 Bean 的數量會大大增長,若是都在啓動時進行初始化會很是耗時。Spring Boot 容許延遲初始化應用程序, 也就是根據須要初始化 Spring Bean,而不是在 Spring Boot 啓動時建立全部的 Bean。這樣的就能夠減小應用程序啓動花費的時間。延遲初始化一般又被稱爲「懶加載」。java
Spring Boot 中的延遲初始化可分爲全局延遲初始化和局部初始化。spring
注意:如下特性在 Spring Boot 2.2.x 中存在
全局初始化咱們能夠經過編程的方式來實現,須要咱們來改變 Spring Boot Main方法的寫法。編程
一般咱們的 Main 方法是這樣的,注意這裏還沒聲明全局懶加載:app
/** * @author felord.cn * @since 2020/3/31 22:53 */ @SpringBootApplication public class DemoSpringbootApplication { @Lazy public static void main(String[] args) { SpringApplication.run(DemoSpringbootApplication.class,args); } }
全局懶加載寫法一:測試
/** * @author felord.cn * @since 2020/3/31 22:53 */ @SpringBootApplication public class DemoSpringbootApplication { @Lazy public static void main(String[] args) { SpringApplication sa = new SpringApplication(DemoSpringbootApplication.class); sa.setLazyInitialization(true); sa.run(args); } }
全局懶加載寫法二:ui
/** * @author felord.cn * @since 2020/3/31 22:53 */ @SpringBootApplication public class DemoSpringbootApplication { @Lazy public static void main(String[] args) { SpringApplicationBuilder sab = new SpringApplicationBuilder(DemoSpringbootApplication.class); sab.lazyInitialization(true).run(args); } }
上面的寫法一和寫法二都是咱們經過編程方式定製一些 Spring Boot 特性,大多數都是全局特性。包括本文講述的 「懶加載」。this
咱們還能夠採起更簡單的配置文件(application.properties)的方式來配置延遲初始化:spa
# 默認是關閉的 false spring.main.lazy-initialization=true
當咱們開啓了全局的延遲加載後,在 Web 應用程序中將致使許多與 Web 相關的 Bean 直到收到第一次 HTTP 請求後才被初始化。code
控制器:blog
/** * @author felord.cn * @since 2020/3/31 23:31 */ @RestController @RequestMapping public class FooController { private FooService fooService; public FooController(FooService fooService) { System.out.println("fooController init...") this.fooService = fooService; } @GetMapping("/req") public Map<String, String> demo() { System.out.println("Preparing HTTP request..."); return fooService.response(); } }
服務層:
/** * @author felord.cn * @since 2020/3/31 23:36 */ @Service public class FooService { public FooService() { System.out.println("fooService init ..."); } public Map<String, String> response() { Map<String, String> map = new HashMap<>(); map.put("msg","from fooService"); return map; } }
調用 /req
接口後咱們發現,不僅僅 FooController
和 FooService
在第一次調用初始化,連 Spring MVC 核心 DispatcherServlet
都是第一次調用時初始化。
若是咱們不想讓全局延遲初始化做用於個別的 Bean 怎麼辦?咱們能夠在這個 Bean 上聲明註解 @Lazy(value = false)
便可。你能夠改寫 2.1 的代碼本身試一試。這個 @Lazy
做用於局部,並經過布爾值 value
來控制是否延遲初始化。狀況是這樣的:
@Lazy(value = false)
標記的 Bean 會被當即加載。@Lazy
標記的 Bean 會被延遲加載。請注意:@Lazy
會影響到@Configuration
下聲明的 Bean
延遲初始化的缺點是,若是錯誤配置的 Bean 是延遲初始化的,則在啓動期間將再也不發生故障,而且只有在初始化 Bean 時錯誤纔會暴露出來,因此必定要通過嚴格的測試。
同時還必須注意確保 JVM 具備足夠的內存來容納全部應用程序的 Bean,而不單單是啓動期間初始化的 Bean。所以建議在啓用延遲初始化以前先對 JVM 的堆大小進行必要的檢測和微調以保證不會溢出。
那些初始化耗時,具備複雜邏輯,並且不是啓動的必要選擇的 Bean 應當被延遲初始化。
今天對 Spring Boot 如何進行延遲初始化進行了講解,同時也說明了一些注意事項。間接地也對 Main 方法的幾種姿式也進行了展現,但願對你的實際開發有所幫助。關注公衆號:Felordcn 將自動獲取技術乾貨資料。