需求描述
當我們想要利用SpringBoot封裝一套組件並發布給第三方使用時,我們就不得不考慮我們的組件能否被使用者正確引入使用,本文章講解的是項目打包成 jar 包后 Spring 配置類未掃描、未注冊Bean的解決方案。
解決方案
此處提供三種解決方案,友好型依次提升。
① 使用者手動配置 basePackages
② 使用者通過注解方式啟用配置
③ SpringBoot 主動發現
目前以兩個項目來作為測試:
springboot_jar_third:它將作為第三方組件以jar包的方式注入到下面的項目中
springboot_jar_import:服務由該項目啟動
第一種:使用者手動配置 basePackages (對組件開發者最為簡單,對使用者最為繁瑣)
使用此方式,對組件開發者最為簡單,不需要對項目進行任何其余配置,我們只需要在測試環境使用功能后直接打包發布。但是使用者使用時需要手動配置 basePackages,假設我們的組件的包基礎為:“com.example”,
這個jar包中只有一個請求地址/hello ,如果想在另一個項目中引用,可以將這個項目打成jar包(mvn clean install),加入另一個項目的pom文件中
springboot_jar_third項目:
springboot_jar_import項目中添加springboot_jar_third jar包:
<dependency> <groupId>com.example</groupId> <artifactId>springboot_jar_third</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
如果想要springboot_jar_import項目啟動時使用springboot_jar_third jar中的hello請求方法,則需要掃描springboot_jar_third中的com.example基礎包,
配置方式: 在SpringBoot啟動類或能被Spring發現的 Configuration 類上增加
@ComponentScan(basePackages={"com.example"})
通過此方式配置后,Spring會在啟動時掃描 com.example 這個包,我們的組件自然而然也會被注冊為Spring Bean
此時啟動項目SpringbootJarImportApplication,輸入localhost:8080/hello,便可以獲取到該請求
第二種方式:通過注解方式引入(在特定的需求環境使用)
第一種方式需要使用者手動進行 basePackages 配置,當使用者忘記配置時,我們的組件則不會生效,第二種雷同,只不過配置方式有變
首先來看看我們項目(組件)的文件結構
ExampleConfig則為我們主要配置類,相當於我們組件的入口,代碼如下
package com.example.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.example") public class ExampleConfig { }
其中,第一行是聲明為一個配置類
第二行為設置自動掃描包,讓Spring能夠發現我們封裝的組件的其他 Spring Bean
到這兒還遠遠沒完,因為我們的目的是使用者通過注解才能發現該配置類,所以我們還需要建立一個注解類,此處取名為 EnableExampleConfig,我們來看看EnableExampleConfig中的代碼:
package com.example.config; import org.springframework.context.annotation.Import; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({ExampleConfig.class}) public @interface EnableExampleConfig { }
關鍵代碼為第 4 行,此行是代碼導入EnableExampleConfig 類,也就是我們前面的配置類。
自此,我們的任務就完成了,剩下的步驟就交於使用者了。
當使用者使用我們組件,需要在能被Spring發現到的 Configuration 上使用我們的注解,代碼如下:
這樣,當用戶啟動程序時,Spring就會將 ExampleConfig 注冊到Bean,然后讀取ExampleConfig中的 @ComponentScan 注解,就實現了我們組件全包被Spring覆蓋
第三種:這也是本文介紹的最后一種(Spring Boot Starter),對組件開發者和使用者都比較友好,故推薦使用,如遇復雜業務,可在第二種和第三種中取舍
此方法最關鍵的為
resources/META-INF/spring.factories 文件,當項目啟動時,Spring會掃描所有jar包下面的 spring.factories 文件,進行相應的自動配置處理,此處我們不進行深入講解,只看看基本配置
其中 org.springframework.boot.autoconfigure.EnableAutoConfiguration 代表自動配置的 key,即代表需要自動配置哪些類,\ 可以理解為一個換行符,則該行下面的每行當做一個參數
# Auto Configure # 定義自動裝配config類,當系統引入該jar包時, spring上下文將初始化這些config類
org.springframework.boot.autoconfigure.EnableAutoConfiguration
第二行則為我們剛才看見的配置類的全路徑,如果需要 Spring 自動配置多個類,我們依行寫入它的全路徑即可
當做完這一步,我們的組件就可以打包了,然后使用者只需要引入我們的jar包,Spring就會在啟動時對我們 spring.factories 中的所有配置類進行自動配置,此時不需要進行包掃描,服務啟動之后便可以將第三方組件引用過來
參考網址:
