分享目標
- 剖析自動化配置原理。
- 如何開發自己的自動化配置。
- 案例分析實踐。
本篇建立在你已經會SpringBoot的基本使用上。
SpringBoot是你進階掌握SpringCloud的必須裝備
配置標準化&外部化
1、統一配置文件名稱
統一命名:application,支持properties\yml兩種格式
2、配置屬性支持繼承,相同後者覆蓋前者
application.yml
./config/application-{profile}.yml
# application.yml
spring:
profiles:
active: ${ENV:dev}
biguava:
tags: it's me
msg: hello world
---
spring:
profiles: dev
biguava:
tags: it's you
---
# 最終得到結果:
biguava:
tags: it's you
msg: hello world
方式一:單獨一個 Model.class 文件
package com.ts;
/**
* biguava配置
*/
@ConfigurationProperties(prefix = "biguava",ignoreInvalidFields = true)
public class Biguava {
String tags;
String msg;
public void setTags(String tags){
this.tags = tags;
}
public String getTags(){
return this.tags;
}
...
}
方式二:直接在需要用個的地方使用@Value
@Configuration
public class BiguavaUtil{
@Value("${biguava.tags}")
String tags;
@Value("${biguava.msg}")
String msg;
}
3、激活profiles方式:
java -jar xxxx.jar --spring.profiles.active=dev,hsqldb --biguava.msg="just for test"
配置屬性生效存在優先級(1-17:高-低):
Auto-configuration
1、自動配置啓動流程
重要知識點:
- spring-boot-autoconfigur.jar 自動配置實現代碼。
- @EnableAutoConfiguration 開啓自動配置掃描。
- META-INF/spring.factories 啓動掃描類清單文件。
- @Configuration&@ConditionalOnXXXX starter啓動依賴條件,"ConditionalOnBean"。
- spring-boot-autoconfigure-processor.jar 自動生成metadata清單實現包。
- META-INF/spring-autoconfigure-metadata.properties 啓動條件元數據清單。
部分源碼(spring-boot-2.0.6)展示:
EnableAutoConfiguration.java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@import:SpringIOC容器注入工具。
AutoConfigurationImportSelector:掃描jar內spring.factories文件。
SpringFactoriesLoader.class:factories清單加載實現類。
@Conditional: starter啓動判斷條件
搭建自己的starter
以biguava-spring-boot-starter項目(後面統稱biguava)爲例講解。biguava屬於bi-parent子項目,是以"自定義註解"和"bean啓動條件"爲原理來構建starter。
目錄結構展示:
第一步:在pom.xml中引入spring-boot-autoconfigure-processor.jar。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
processor在complie時它會自動生成spring-autoconfigure-metadata.properties。存放ConditionalOnClass啓動依賴和出發條件清單,通過@AutoConfigureBefore、@AutoConfigureAfter來實現組件依賴。注意:要求關鍵字不要和官方相同。
spring-autoconfigure-metadata.properties
#Wed Oct 24 16:39:39 CST 2018
com.biguava.spring.boot.BiguavaAutoConfiguration=
com.biguava.spring.boot.BiguavaAutoConfiguration.Configuration=
第二步: 編寫starter啓動依賴@interface類。
EnableBiguavaConfiguration.class
/**
* biguava啓動註解
* @author: Owen Jia
* @time: 2018/10/23 18:12
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableBiguavaConfiguration {
}
第三步: 配置classpath:/META-INF/spring.factories。
spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.biguava.spring.boot.BiguavaAutoConfiguration
第四步:編寫具體業務實現。
PrintServiceImpl.class,根據配置週期打印時間sample。
/**
* @author: Owen Jia
* @time: 2018/10/3 14:13
*/
public class PrintServiceImpl {
private boolean printEnabled = true;
private int printCycleTime = 1;
public void printTime(){
try {
while (printEnabled){
Thread.sleep(printCycleTime * 1000);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH🇲🇲ss");
System.out.println("current time is " + sf.format(new Date()));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public boolean isPrintEnabled() {
return printEnabled;
}
public void setPrintEnabled(boolean printEnabled) {
this.printEnabled = printEnabled;
}
public int getPrintCycleTime() {
return printCycleTime;
}
public void setPrintCycleTime(int printCycleTime) {
this.printCycleTime = printCycleTime;
}
}
第五步: 開發starter啓動類。@ConditionalOnBean來控制starter啓動,@EnableConfigurationProperties加載starter需要的配置屬性,@Bean控制接口啓動。
BiguavaAutoConfiguration.class
/**
* 自動配置-配置類
* ConditionalOnBean 通過判斷EnableBiguavaConfiguration註解是否使用啓動自動配置
* @author: Owen Jia
* @time: 2018/10/22 18:20
*/
@Configuration
@EnableConfigurationProperties(BiguavaProperties.class)
@ConditionalOnBean(annotation = EnableBiguavaConfiguration.class)
public class BiguavaAutoConfiguration {
@Autowired(required = false)
BiguavaProperties biguavaProperties;
@Bean
@ConditionalOnMissingBean(SayHelloServiceImpl.class)
public SayHelloServiceImpl sayHelloService(){
System.out.println("SayHelloService bean was matched");
System.out.println("Execute Create New Bean: SayHelloServiceImpl");
SayHelloServiceImpl sayHelloService = new SayHelloServiceImpl();
sayHelloService.setBiguavaProperties(biguavaProperties);
return sayHelloService;
}
@Bean
@ConditionalOnProperty(prefix = "biguava.print",value = "enabled",matchIfMissing = true)
public PrintServiceImpl printServiceImplByPro(){
System.out.println("PrintServiceImpl:enabled= " + biguavaProperties.getPrint().isEnabled());
System.out.println("Execute Create New Bean: PrintServiceImpl");
PrintServiceImpl printService = new PrintServiceImpl();
printService.setPrintCycleTime(biguavaProperties.getPrint().getCycleTime());
printService.setPrintEnabled(biguavaProperties.getPrint().isEnabled());
printService.printTime();
return printService;
}
}
第六步: 在main.class添加啓動註解@EnableDubboConfiguration,在application-local.yml文件中添加biguava配置。
WebApp.class
/**
* 服務啓動入口
* @author Owen Jia
*/
@SpringBootApplication
@MapperScan("com.jcc.bi.data.dao")
@ComponentScan(basePackages = "com.jcc.bi.*")
@EnableDubboConfiguration
@EnableBiguavaConfiguration
public class WebApp {
public static void main(String[] args){
SpringApplication app = new SpringApplication(WebApp.class);
app.run(args);
}
}
applicaiton-local.yml
# biguava組件配置
biguava:
level: height
monitorTime: 121
hello:
keys: 1234asdf
desc: i am biguava sample
print:
enabled: true
cycleTime: 5 # 單位:s
AutoConfiguration思想下我們能幹什麼?
案例分析
1.中間件CAT
2.中間件LTS
如何構建零配置的組件?
1、服務組件化
服務是由多個組件模塊組合產生,不同的組合產生不同的服務。將耦合、組件化。
2、組件零配置化
配置抽象化、默認化、封裝一體。
----|||---- 發揮你的想象力和創造力 ----|||----
友情鏈接
Docs: spring-boot-2.0.6。
Sample: bi-parent | biguava-spring-boot-starter。
作者: Owen Jia,歡迎訪問他博客 Owen Blog 。
掃描下方二維碼收藏文章哦~~~