持續原創輸出,點選上方藍字關注我
前言
日常工作中對於Spring Boot
提供的一些啟動器可能已經足夠使用了,但是不可避免的需要自定義啟動器,比如整合一個陌生的元件,也想要達到開箱即用的效果。
在上一章節從底層原始碼介紹了Spring Boot
的自動配置的原理,未讀過的朋友建議看一下:Spring Boot 自動配置原始碼解析
這篇文章將會介紹如何自定義一個啟動器,同時對於自動配置類的執行順序做一個詳細的分析。
如何自定義一個starter?
啟動器的核心其實就是自動配置類,在自動配置原始碼分析的章節已經介紹過,AutoConfigurationImportSelector
是從spring.factories
中載入自動配置類,因此只需要將自定義的自動配置類設定在該檔案中即可。
讀過原始碼的朋友都知道自動配置類常用的一些註解,總結如下:
@Configuration
: 該註解標誌這是一個配置類,「自動配置類可以不加該註解」。@EnableConfigurationProperties
:這個配置也是經常使用了,使得指定的屬性配置生效。一般自動配置類都需要從全域性屬性配置中讀取自定義的配置,這就是一個開關。@ConditionalOnXxxx
:該註解是自動配置類的核心了,自動配置類既要啟動時自動配置,又要保證使用者使用者自定義的配置覆蓋掉自動配置,該註解就是一個條件語句,只有當指定條件成立才會執行某操作。不理解的,請看作者前面的一篇文章:這類註解都不知道,還說用過Spring Boot~@AutoConfigureAfter
:指定自動配置類的執行先後順序,下文詳細介紹。@AutoConfigureBefore
:指定自動配置列的執行先後順序,下文詳細介紹。@AutoConfigureOrder
:指定自動配置類的優先順序,下文詳細介紹。
有了以上準備,自定義一個starter
非常簡單,分為兩個步驟。
1. 準備自己的自動配置類
啟動器的靈魂核心就是自動配置類,因此需要首先建立一個自動配置類,如下:
@Configuration
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE+5)
@ConditionalOnProperty(prefix = "my.auto",name = "enabled",havingValue = "true",matchIfMissing = true)
public class MyCustomAutoConfiguration {
}
以上自動配置類只是作者簡單的按照格式隨手寫了一個,真實開發中需要根據啟動器的業務做預設配置。
2. 將自動配置類設定在spring.factories
標註了@Configuration
註解的自動配置類如果不放在spring.factories
檔案中,僅僅是一個普通的配置類而已。想要其成為自動配置類,需要在spring.factories
檔案中設定,如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.MyCustomAutoConfiguration
經過以上的配置,粗略的啟動器完成了,只需要打包,然後Maven
引入即可工作。
如何指定自動配置類的執行順序?
自動配置類需要定義執行順序嗎?答案:肯定的。比如Mybatis
的自動配置類,肯定要在資料來源的自動配置類之後執行,否則如何建立SqlSessionFactory
?
如何自定義自動配置類的執行順序呢?此時就需要用到上文提到的三個註解,如下:
@AutoConfigureAfter
: 當前配置類在指定配置類之後執行@AutoConfigureBefore
: 當前配置類在指定配置類之前執行@AutoConfigureOrder
:指定優先順序,數值越小,優先順序越高。
分享一個經典的誤區
對於Spring Boot
不是很瞭解的人寫出的程式碼真是「不堪入目」,曾經看過有人在「普通的配置類」上使用@AutoConfigurexxx
註解,如下;
@Configuration
@AutoConfigureBefore(Config2.class)
public class Config1{}
@Configuration
public class Config2{}
是不是感覺很爽,原來還能這麼指定配置類的執行順序.....(此處省略一萬字)
❝可能有時候走了狗屎運給你一種錯覺還真的配置成功了。實際上這種方式是不可行的,以上三個註解只有針對自動配置類才會生效。
❞
原始碼分析自動配置類如何排序?
其實關鍵的程式碼還是在AutoConfigurationImportSelector
中,將自動配置類從spring.factories
載入出來之後會根據條件排序,在selectImports()
方法中最後一行程式碼如下:
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
上面的程式碼則是將排序好的自動配置類返回,跟進程式碼,發現最終的實現都在AutoConfigurationSorter.getInPriorityOrder()
方法中,邏輯如下圖:
具體的流程如上圖,排序也是按照先後順序,如下:
先按照字母排序 按照 @AutoConfigureOrder
優先順序排序最終按照 @AutoConfigureAfter
、@AutoConfigureBefore
排序
❝從上面配置的順序可以知道,最終決定權還是在
❞@AutoConfigureAfter
、@AutoConfigureBefore
這兩個註解。
總結
本文介紹瞭如何自定義一個啟動器以及指定自動配置類的執行順序,通過作者的介紹,希望讀者們能夠理解並靈活運用。
另外作者的第一本PDF
書籍已經整理好了,由淺入深的詳細介紹了Mybatis基礎以及底層原始碼,有需要的朋友公號回覆關鍵詞「Mybatis進階」即可獲取,目錄如下: