springboot自動設定原理以及手動實現設定類

2022-10-01 06:01:53

springboot自動設定原理以及手動實現設定類

1、原理

spring有一個思想是「約定大於設定」。

設定類自動設定可以幫助開發人員更加專注於業務邏輯開發,springboot在啟動的時候可以把一些設定類自動注入到spring的IOC容器裡,專案執行之後就可以直接使用這些設定類的屬性和方法等。

springboot有一個全域性組態檔,application.properties / application.yml,各種屬性都可以在檔案中進行自定義設定。

自動設定實現原理:

我們都知道專案的入口是 @SpringBootApplication 註解,這個註解標識了該類是springboot的啟動類,那我們就從它入手一探究竟。

我們可以看到這個註解是一個複合註解,其中的 @EnableAutoConfiguration 註解表示開啟自動設定,這個註解也是複合註解。

我們可以看到它匯入了一個名為AutoConfigurationImportSelector的類,那麼這個類的作用是什麼呢?

我們繼續往下看,可以看到 selectImports( ) 方法

selectImports 這個方法通過呼叫 SpringFactoriesLoader.loadFactoryNames() 方法掃描spring-boot-autoconfigure-xxx.jar/META-INF路徑下的 spring.factories檔案,通過類的全路徑拿到需要設定的類名,然後通過反射將其全部注入IOC容器中。

每個設定類都有一些屬性,XXXAutoConfiguration自動設定類,會有一個@EnableConfigurationProperties註解,它的引數是一個XXXProperties類,該註解的作用是把XXXProperties類的範例載入到Spring的IOC容器中,而XXXProperties類中的屬性就是自動設定的屬性。

XXXProperties類有一個註解@ConfigurationProperties,該註解可以掃描全域性組態檔application.properties或者application.yml檔案中以prefix開頭的一組設定繫結到DataSourceProperties範例的屬性上,實現自動設定。

// 全域性掃描注入 組態檔中以spring.datasource開頭的值
@ConfigurationProperties(
    prefix = "spring.datasource"
)

2、手動寫一個自動設定類

有了上面的理解,我們可以自己動手寫一個自動設定類。

自動設定類做的事情就是把@EnableConfigurationProperties註解標識的類注入到IOC容器。

2.1、所以我們先寫一個自動設定類SeviceAutoConfiguration

package com.ycw.autoconfig.configuration;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author Administrator
 * @date 2022-09-30 21:51
 */
@Slf4j
@Configuration  // 自動設定類
@EnableConfigurationProperties(ServiceProperties.class)     // 標識XXXProperties類的範例
public class SeviceAutoConfiguration {

}

2.2、寫真正要加入容器的類ServiceProperties

package com.ycw.autoconfig.configuration;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author Administrator
 * @date 2022-09-30 21:50
 */
@Data
@Slf4j
@ConfigurationProperties(prefix = "myconfig")   // 掃描全域性組態檔完成屬性注入
public class ServiceProperties {
	private String name;
	public void print(){
		log.info("自動設定成功! " + name);
	}
}

2.3、在resources目錄下新建目錄META-INF,新建檔案spring.factories完成對自動設定類全路徑設定

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ycw.autoconfig.configuration.SeviceAutoConfiguration

2.4、在全域性組態檔application.properties中新增屬性注入

2.5、寫一個Controller測試,ControllerTest

package com.ycw.autoconfig.controller;

import com.ycw.autoconfig.configuration.ServiceProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author Administrator
 * @date 2022-09-30 21:54
 */
@RestController
public class ControllerTest {
	@Resource
	private ServiceProperties serviceProperties;
	@RequestMapping("test")
	public void test(){
		serviceProperties.print();
	}
}

執行之後我們可以看到:

分析一下這個過程:

  1. 啟動類@SpringBootApplication通過spring.factories檔案中的org.springframework.boot.autoconfigure.EnableAutoConfiguration找到了SeviceAutoConfiguration

  2. @Configuration 註解的類SeviceAutoConfiguration被springboot掃描到後,它所標識的@EnableConfigurationProperties(ServiceProperties.class) 開始進入被注入容器的過程

  3. ServiceProperties 類的註解@ConfigurationProperties(prefix = "myconfig") 使得springboot掃描全域性組態檔application.properties

  4. application.properties中的 myconfig.name=yangchuanwei 被注入到屬性name中,自此ServiceProperties已經被自動設定成功!


獲取demo地址可以關注公眾號【靠譜楊的挨踢生活】,回覆【autoconfig】獲取下載連結。