1. 程式人生 > >【SpringBoot 基礎系列】實現一個自定義配置載入器(應用篇)

【SpringBoot 基礎系列】實現一個自定義配置載入器(應用篇)

![](https://spring.hhui.top/spring-blog/imgs/200507/logo.jpg) > [【SpringBoot 基礎系列】實現一個自定義配置載入器(應用篇)](https://mp.weixin.qq.com/s?__biz=MzU3MTAzNTMzMQ==&mid=2247484640&idx=1&sn=5ac20b68d7b539295dabc0c2aaf81314) Spring 中提供了`@Value`註解,用來繫結配置,可以實現從配置檔案中,讀取對應的配置並賦值給成員變數;某些時候,我們的配置可能並不是在配置檔案中,如存在 db/redis/其他檔案/第三方配置服務,本文將手把手教你實現一個自定義的配置載入器,並支援`@Value`的使用姿勢 ## I. 環境 & 方案設計 ### 1. 環境 - SpringBoot `2.2.1.RELEASE` - IDEA + JDK8 ### 2. 方案設計 自定義的配置載入,有兩個核心的角色 - 配置容器 `MetaValHolder`:與具體的配置打交道並提供配置 - 配置繫結 `@MetaVal`:類似`@Value`註解,用於繫結類屬性與具體的配置,並實現配置初始化與配置變更時的重新整理 上面`@MetaVal`提到了兩點,一個是初始化,一個是配置的重新整理,接下來可以看一下如何支援這兩點 #### a. 初始化 初始化的前提是需要獲取到所有修飾有這個註解的成員,然後藉助`MetaValHolder`來獲取對應的配置,並初始化 為了實現上面這一點,最好的切入點是在 Bean 物件建立之後,獲取 bean 的所有屬性,檢視是否標有這個註解,可以藉助`InstantiationAwareBeanPostProcessorAdapter`來實現 #### b. 重新整理 當配置發生變更時,我們也希望繫結的屬性也會隨之改變,因此我們需要儲存`配置`與`bean屬性`之間的繫結關係 `配置變更` 與 `bean屬性的重新整理` 這兩個操作,我們可以藉助 Spring 的事件機制來解耦,當配置變更時,丟擲一個`MetaChangeEvent`事件,我們預設提供一個事件處理器,用於更新通過`@MetaVal`註解繫結的 bean 屬性 **使用事件除了解耦之外,另一個好處是更加靈活,如支援使用者對配置使用的擴充套件** ## II. 實現 ### 1. MetaVal 註解 提供配置與 bean 屬性的繫結關係,我們這裡僅提供一個根據配置名獲取配置的基礎功能,有興趣的小夥伴可以自行擴充套件支援 SPEL ```java @Target({ElementType.FIELD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface MetaVal { /** * 獲取配置的規則 * * @return */ String value() default ""; /** * meta value轉換目標物件;目前提供基本資料型別支援 * * @return */ MetaParser parser() default MetaParser.STRING_PARSER; } ``` 請注意上面的實現,除了 value 之外,還有一個 parser,因為我們的配置 value 可能是 String,當然也可能是其他的基本型別如 int,boolean;所以提供了一個基本的型別轉換器 ```java public interface IMe