SpringBoot如何自定義starter

1. 什麼是starter

Springboot的出現極大的簡化瞭開發人員的配置,而這之中的一大利器便是springboot的starter,starter是springboot的核心組成部分,為什麼說引入如下依賴就滿足瞭日常web開發?

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

而不使用springboot時,需要引入spring-webspring-webmvcspring-aop等等。實際上那些必要的依賴在spring-boot-starter-web中已經被引入瞭,引入這個組名就引入瞭所有的依賴。

2. 自動配置原理

springboot在啟動的時候會加載主配置類,開啟瞭@EnableAutoConfiguration

@EnableAutoConfiguration的作用:

利用AutoConfigurationImportSelector給容器導入一些組件。
查看selectImports方法的內容,返回一個AutoConfigurationEntry
可以看到SpringFactoriesLoader.loadFactoryNames,繼續看又調用瞭loadSpringFactories方法,獲取META-INF/spring.factories資源文件。這個spring.factories文件也是一組一組的key=value的形式,其中一個key是EnableAutoConfiguration類的全類名,而它的value是一個xxxxAutoConfiguration的類名的列表,這些類名以逗號分隔,最後都加入到容器中,用來做自動配置,每一個自動配置類都可以進行自動配置功能使用HttpEncodingAutoConfiguration來解釋自動裝配原理。根據當前不同的條件判斷,決定這個配置類是否生效!

2.1 自動配置生效

每一個XxxxAutoConfiguration自動配置類都是在某些條件之下才會生效的,這些條件的限制在Spring Boot中以註解的形式體現,

常見的條件註解有如下幾項:

  • @Conditional擴展註解 作用
  • @ConditionalOnJava 系統的java版本是否符合要求
  • @ConditionalOnBean 容器中存在指定Bean
  • @ConditionalOnMissingBean 容器中不存在指定Bean
  • @ConditionalOnExpression 滿足SpEL表達式
  • @ConditionalOnClass 系統中有指定的類
  • @ConditionalOnMissingClass 系統中沒有指定的類
  • @ConditionalOnSingleCandidate 容器中隻有一個指定的Bean,或者是首選Bean
  • @ConditionalOnProperty 系統中指定的屬性是否有指定的值
  • @ConditionalOnResource 類路徑下是否存在指定資源文件
  • @ConditionOnWebApplication 當前是web環境
  • @ConditionalOnNotWebApplication 當前不是web環境

自動配置原理總結如下:

  •     1、Spring Boot啟動的時候會通過@EnableAutoConfiguration註解找到META-INF/spring.factories配置文件中的所有自動配置類進行加載
  •     2、這些自動配置類都是以AutoConfiguration結尾來命名的,它實際上就是一個JavaConfig形式的Spring容器配置類
  •     3、自動配置類通過以Properties結尾命名的類中取得在全局配置文件中配置的屬性如:server.port,而XxxxProperties類是通過@ConfigurationProperties註解與全局配置文件中對應的屬性進行綁定的。

3. 自定義starter

spring-boot有兩種starter:

一種是內部已經支持的,其通過@ConditionalOnClass來實決定是否例化(ConditionalOnClass是指當在classpath發現需要的依賴的類時實例化),想要啟動這個服務,隻要要配置上對應的starter,這個starter就能把所需要的jar給關聯上。
一種是第三方的,比如mybatis等。原理是一樣的,就是在你已經實現的服務代碼之上封裝一層配置代碼就行。
基於這個機制,我們自己也可以實現一個。自定義starter,我們要做的事情是兩個:確定依賴和編寫自動配置。我們重點要做的就是編寫自動配置,我們之前寫過一些自動配置,主要是註解配置的使用,主要的註解有:

  • @Configuration :指定這個類是一個配置類
  • @ConditionalOnXXX :在指定條件成立的情況下自動配置類生效
  • @AutoConfigureAfter:指定自動配置類的順序
  • @Bean:給容器中添加組件
  • @ConfigurationPropertie:結合相關xxxProperties類來綁定相關的配置
  • @EnableConfigurationProperties:讓xxxProperties生效加入到容器中

3.1 命名規范

SpringBoot提供的starter以spring-boot-starter-xxx的方式命名的。官方建議自定義的starter使用xxx-spring-boot-starter命名規則。以區分SpringBoot生態提供的starter。

官方命名空間:

  • 前綴:“spring-boot-starter-”
  • 模式:spring-boot-starter-模塊名
  • 舉例:spring-boot-starter-webspring-boot-starter-jdbc

自定義命名空間:

  • 後綴:“-spring-boot-starter”
  • 模式:模塊-spring-boot-starter
  • 舉例:druid-spring-boot-startermybatis-spring-boot-starter

4.總結

Starter可以理解為一個可拔插式的插件,提供一系列便利的依賴描述符,您可以獲得所需的所有Spring和相關技術的一站式服務。應用程序隻需要在maven中引入starter依賴,SpringBoot就能自動掃描到要加載的信息並啟動相應的默認配置。

4.1為什麼要自定義starter?

在我們的日常開發工作中,經常會有一些獨立於業務之外的配置模塊,我們經常將其放到一個特定的包下,然後如果另一個工程需要復用這塊功能的時候,需要將代碼硬拷貝到另一個工程,重新集成一遍,麻煩至極。如果我們將這些可獨立於業務代碼之外的功能配置模塊封裝成一個個starter,復用的時候隻需要將其在pom中引用依賴即可。

4.2 自定義starter的案例

以下案例由筆者工作中遇到的部分場景

動態數據源。 — fs-dynamic-starter
登錄模塊(權限)。— fs-auth-client-starter
基於AOP技術實現日志切面。—fs-common-starter
案例地址:https://gitee.com/Manoninsight/fullset/tree/master/fs-starter

這裡還有一個小細節,你如果仔細查看我的案例會發下一個問題,就是我自定義的starter裡並沒有META-INF/spring.factories配置文件,為什麼還能生效呢?這是因為我的項目用的統一的包路徑:com.fs。spring配置默認會掃描當前的包路徑,所以能加載到。但是筆者建議還是加上META-INF/spring.factories配置文件。

到此這篇關於SpringBoot如何自定義starter的文章就介紹到這瞭,更多相關SpringBoot自定義starter內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: