1. 程式人生 > >通過例項及原始碼分析關於SpringBoot啟動類啟動時自動配置問題

通過例項及原始碼分析關於SpringBoot啟動類啟動時自動配置問題

SpringBoot啟動類大家都不陌生,只要在main方法上增加一個@SpringBootApplication註解,就可以啟動了。
我們點開該註解
這裡寫圖片描述

其中關鍵註解為@EnableAutoConfiguration,再次跟進
這裡寫圖片描述
其中引入了EnableAutoConfigurationImportSelector.class,解釋見下圖
這裡寫圖片描述

其中關鍵的方法為getCondidateConfiguration(metadata attributes)
這裡寫圖片描述
中的SpringFactoriesLoader.loadFactoryNames(..)方法。
這裡寫圖片描述
SpringFactoriesLoader預設查詢的位置就是”META-INF/spring.factories”,而在spring-boot-autoconfigure-1.4.7.jar中就有一個spring.factories。在其中配置了各種各樣的AutoConfigure類。到了這一步,我們算是找到了springBoot啟動時自動配置的源頭。就是在spring.factories中我們通過org.springframework.boot.autoconfigure.EnableAutoConfiguration配置的啟動時自動載入的自動配置類。所有的自動配置類採用了Spring4.0+的JAVA配置方法(即@

[email protected])進行配置

現在我們手寫一個自動配置包
1:首先我們建立一個SpringBoot的quickstart,然後在POM檔案中依賴

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>1.3.4.RELEASE</version>
    </dependency
>

2:我們以如下圖路徑建立一個spring.factories的properties檔案。
這裡寫圖片描述
建立好後。我們來建立一個自動配置類。為了節省空間,筆者這裡就不帶引入的包了。
通過引入了
@EnableConfigurationProperties(HelloServiceProperties.class)聲明瞭配置,就可以通過@Autowired將HelloServiceProperties的例項注入進來。

//這個註解代表這個類是個配置檔案
@Configuration
//這個註解代表會去自動載入HelloServiceProperties中的所有屬性
@EnableConfigurationProperties
(HelloServiceProperties.class) //這個註解代表會去import com.starrk.service.HelloService;這個路徑上尋找是否有類,如果有這個類,才進行載入bean @ConditionalOnClass(HelloService.class) //此註解會自動去application.properties中尋找prefix為hello,name/value(這兩個屬性是互斥的,name是value的別名)為starrk的 //當他的值為true時,載入當前類中的所有bean,當找不到時,設定為false,即不載入。 @ConditionalOnProperty(prefix = "hello",name = "starrk",havingValue = "true",matchIfMissing = false) public class HelloServiceAutoConfigure { @Autowired private HelloServiceProperties helloServiceProperties; @Bean @ConditionalOnMissingBean(HelloService.class)//代表當沒有例項時,建立一個例項。 public HelloService helloService(){ HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }

3:建立一個自動載入屬性的類來繫結你在application.properties中配置的屬性。
而HelloServiceProperties類上,如下圖所示進行了配置檔案繫結

@Data
@ConfigurationProperties(prefix = "hello")
public class HelloServiceProperties {
    private static final String MSG = "may the force be with you";
    private String msg =MSG;
}

這裡的@Data是使用了Lombok外掛,自動get/set,如果不使用可以手寫,都是一樣的。如果想使用可參考筆者文章
http://blog.csdn.net/weixin_39781526/article/details/78870944
@ConfigurationProperties是將HelloServiceProperties與你在Application.properties中的屬性進行了繫結,即如下圖
這裡寫圖片描述

4:然後我們建立一個服務類HelloService

@Data
public class HelloService {
    private String msg;

    public String hello(){
        return "hello, "+msg;
    }

}

4:裝載我們的自動配置類在spring.factories中

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.starrk.autoconfig.HelloServiceAutoConfigure

至此。自動配置包我們就建立完成。下面,我們來驗證一下是否成功
建立一個SpringBoot專案,然後依賴我們剛建立的包

    <dependency>
          <groupId>com.starrk</groupId>
          <artifactId>autowired</artifactId>
          <version>1.0-SNAPSHOT</version>
      </dependency>

建立啟動類

@RestController
@SpringBootApplication
public class Application {
    @Autowired
    private HelloService helloService;
    @RequestMapping("/")
    public String hello(){
        return helloService.getMsg();
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

配置application.properties/yml設定啟動埠(可省略,隨意)
設定埠為9000
啟動當前的SpringBoot專案
得到結果
這裡寫圖片描述
我們將自動配置包中的application.properties中的檔案裡的hello.msg註釋掉。
預期得到結果為may the force be with you
這裡寫圖片描述
至此,自動配置的手寫及驗證完成。而這就是Spring自動配置的過程。