SpringBoot Starter緣起
SpringBoot通過SpringBoot Starter零配置自動載入第三方模組,只需要引入模組的jar包不需要任何配置就可以啟用模組,遵循約定大於配置的思想。
那麼如何編寫一個SpringBoot Starter呢?我們需要考慮如下幾個問題:
- 如何讓SpringBoot發現我們編寫的模組?
- 如何讓模組讀取SpringBoot的配置文件?
- 如果用戶沒有在配置文件中配置必要的配置項,如何默認禁用模組?
- 如何讓SpringBoot知道模組有哪些配置項目,方便用戶配置配置文件?
一.模組的發現
由於SpringBoot默認的包掃描路徑是主程式所在包及其下面的所有子包裡面的組件,引入的jar包下的類是不會被掃描的。那麼如何去載入Starter的配置類呢?
SpringBoot約定會掃描Starter jar包META-INF目錄下的spring.factories文件,只需要在spring.factories文件里配置要載入的類就可以了。下面的是Arthas的配置文件(arthas-spring-boot-starter-3.6.3.jar,Arthas是Alibaba開源的Java診斷工具。)。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alibaba.arthas.spring.ArthasConfiguration,\ com.alibaba.arthas.spring.endpoints.ArthasEndPointAutoConfiguration
這樣SpringBoot在啟動的時候就會自動載入這些類存放到容器中管理。
二.模組讀取SpringBoot的配置文件
ArthasConfiguration的源碼:
@ConditionalOnProperty(
name = {"spring.arthas.enabled"},
matchIfMissing = true
)
@EnableConfigurationProperties({ArthasProperties.class})
public class ArthasConfiguration {
@ConfigurationProperties(
prefix = "arthas"
)
@ConditionalOnMissingBean(
name = {"arthasConfigMap"}
)
@Bean
public HashMap<String, String> arthasConfigMap() {
return new HashMap();
}
@ConditionalOnMissingBean
@Bean
public ArthasAgent arthasAgent(@Autowired @Qualifier("arthasConfigMap") Map<String, String> arthasConfigMap, @Autowired ArthasProperties arthasProperties) throws Throwable {
arthasConfigMap = StringUtils.removeDashKey(arthasConfigMap);
ArthasProperties.updateArthasConfigMapDefaultValue(arthasConfigMap);
String appName = this.environment.getProperty("spring.application.name");
if (arthasConfigMap.get("appName") == null && appName != null) {
arthasConfigMap.put("appName", appName);
}
Map<String, String> mapWithPrefix = new HashMap(arthasConfigMap.size());
Iterator var5 = arthasConfigMap.entrySet().iterator();
while(var5.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry)var5.next();
mapWithPrefix.put("arthas." + (String)entry.getKey(), entry.getValue());
}
ArthasAgent arthasAgent = new ArthasAgent(mapWithPrefix, arthasProperties.getHome(), arthasProperties.isSlientInit(), (Instrumentation)null);
arthasAgent.init();
logger.info("Arthas agent start success.");
return arthasAgent;
}
}
我們發現類上面兩個註解EnableConfigurationProperties和ConditionalOnProperty。這兩個註解的作用如下:
- EnableConfigurationProperties用來指定要載入的配置類,配置類用來載入SpringBoot的配置文件,SpringBoot配置文件中可以指定Arthas的啟動參數。如果你不需要任何參數,則可以不指定EnableConfigurationProperties。
@ConfigurationProperties(
prefix = "arthas"
)
public class ArthasProperties {
private String ip;
private int telnetPort;
private int httpPort;
private String tunnelServer;
private String agentId;
private String appName;
private String statUrl;
}
- ConditionalOnProperty通過讀取SpringBoot配置文件的指定參數判斷是否啟用組件,如果判斷為False,ArthasConfiguration里的Bean就不會被載入到容器中,即組件的開關。Arthas讀取spring.arthas.enabled來判斷是否載入組件。如果你想默認啟動,沒有開關,則可以不指定ConditionalOnProperty。
三.編寫自己的Starter
我們寫個簡單的Starter,不載入配置文件,並且默認啟動的Starter。IDE用的是是IDEA社區版。
3.1創建一個SpringBootStarter項目
3.1.1 新建項目,選擇使用Maven構建。
3.1.2 然後創建spring.factories文件和配置類。
3.1.3 spring.factories寫入配置類的全稱。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.bjgoodwil.SpringBootStarterConfiguration
3.1.4 Maven打包
使用Maven的site命令打包jar到自己的本地倉庫中。
3.2在SpringBoot項目中引入jar
打開一個SpringBoot項目,在pom文件中引入Jar(直接拷貝Starter pom文件中的參數),啟動SpringBoot項目,控制台就會列印配置類的列印語句。
<!--自定義Starter-->
<dependency>
<groupId>com.bjgoodwill</groupId>
<artifactId>springbootstarter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>