背景
我參加SpringBoot專案開發也已經五個多月時間了,專案遇到一個大資料量文本的取存問題,DBA不允許我們存text或者blob型別的資料在MySQL中,不得已采取了ElasticSearch作為一個中間資料庫使用,然后根據網上的方法把maven依賴匯入,application.properties粘貼過來,發現已經引入了ElasticSearch這個組件,最后把問題解決了,
但是這也引發了我的思考,為啥SpringBoot可以自動識別并且幫我初始化ES呢?閱讀了SpringBoot原始碼,我按照我的理解講一下SpringBoot的自動配置,
理論知識
創建一個SpringBoot專案,它會幫我們生成我們開發者所需要的環境,它的一個注解@SpringBootApplication可以幫助我們開發者開啟自動配置并且初始化我們所需要的bean,

但是@SpringBootApplication為什么可以這樣呢?
點進去看這個注解,原來這個注解是一個復合注解,里面還有一個@EnableAutoConfiguration,顧名思義就是自動開啟配置,

然后再點進去查看它的原始碼

發現原來SpringBoot自動配置的關鍵就是這個注解@Import({AutoConfigurationImportSelector.class}),點進去查看原始碼

它的作用就是匯入AutoConfigurationImportSelector的selectImports方法,通過SpringFactoriesLoader.loadFactoryNames()掃描所有META-INF/spring.factories的jar包,然后spring-boot-autoconfigure-2.4.1.jar里面有一個spring.factories檔案,該檔案由一堆key=value組成,其中key是EnableAutoConfiguration類的全類名,而value是xxxAutoConfiguration的類名串列,以逗號分隔,


上面所列出來的org.springframework.boot.autoconfigure.xxx.yyyAutoConfiguration串列會被初始化到Spring容器中,
當SpringBoot專案啟動時,@SpringBootApplication在啟動類SpringApplication.run(xxx.class)的內部會執行selectImports()方法,找到所有自動配置類的全限定名對應的class,然后把所有的自動配置類加載到Spring容器中,
那么這么多xxxAutoConfiguration類都會被加載嗎?
答案是不會,因為注解類會有一個@ConditionalOnClass注解,只要在當前的類路徑下找到對應的類才會被加載,否則放棄加載并且初始化到Spring容器中,
這就很好理解為啥SpringBoot專案引入一個依賴就能自動幫你初始化bean了吧,
舉例說明
舉例我最近用的elasticSearch的配置資訊如何加載到bean容器中的,
引入組件所需要的maven依賴:

配置application.properties基礎資訊:

為何要這樣配置呢?原始碼告訴你答案,
springboot自動配置全都是由autoconfigure注入的,打開maven引入的autoconfigure的jar包

SpringBoot加載會讀取里面的spring.factories檔案

所有的配置都是由org.springframework.boot.autoconfigure.EnableAutoConfiguration來完成注入,格式都是為org.springframework.boot.autoconfigure.xxx.yyyAutoConfiguration,
拿我們配置的elasticsearch來說明一下,點進去看它配置的原始碼


可以看到有一個注解@EnableConfigurationProperties,就是用來配置和初始化bean的,點進去看ElasticsearchRestClientProperties的配置資訊

一切恍然大悟,原來這里的@ConfigurationProperties(prefix=“spring.elasticsearch.rest”)已經規定了組態檔該如何寫了,就是限制了前綴"spring.elasticsearch.rest",后面的uris的型別是List代表它支持集群,可以加載多個服務器,然后它們有對應的get/set方法可以幫助我們開發者注入,這就對應上我們的application.properties檔案了吧,

就是通過這種方式注入到bean容器并且初始化的,這就是springboot的“約定大于配置”,
類比其他配置資訊
我直接把springboot中redis的約定貼出來,你們也可以對比一下你們自己的專案配置,知道為什么要這樣寫就行了,


總結
通過這一次專案引入ElasticSearch引發的一場SpringBoot自動配置原始碼閱讀,我覺得還是受益匪淺的,希望以上的內容對正在學SpringBoot或者已經作業的開發者們有幫助,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/235530.html
標籤:其他
