spring-boot學習分享-進階篇(自動配置專篇)

分享目標

  1. 剖析自動化配置原理。
  2. 如何開發自己的自動化配置。
  3. 案例分析實踐。

本篇建立在你已經會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、自動配置啓動流程
AutoConfiguration生命週期
重要知識點:

  1. spring-boot-autoconfigur.jar 自動配置實現代碼。
  2. @EnableAutoConfiguration 開啓自動配置掃描。
  3. META-INF/spring.factories 啓動掃描類清單文件。
  4. @Configuration&@ConditionalOnXXXX starter啓動依賴條件,"ConditionalOnBean"。
  5. spring-boot-autoconfigure-processor.jar 自動生成metadata清單實現包。
  6. 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

CAT案例

2.中間件LTS

LTS案例

如何構建零配置的組件?

零配置組件化

1、服務組件化

服務是由多個組件模塊組合產生,不同的組合產生不同的服務。將耦合、組件化。

2、組件零配置化

配置抽象化、默認化、封裝一體。

----|||---- 發揮你的想象力和創造力 ----|||----

友情鏈接

Docs: spring-boot-2.0.6
Sample: bi-parent | biguava-spring-boot-starter

作者: Owen Jia,歡迎訪問他博客 Owen Blog


掃描下方二維碼收藏文章哦~~~
點擊收藏該篇文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章