SpringBoot2.x基礎篇:談談SpringBoot內提供的這幾種配置繫結

恆宇少年發表於2020-04-07

SpringBoot2.x基礎篇:談談SpringBoot內提供的這幾種配置繫結

知識改變命運,擼碼使我快樂,2020繼續遊走在開源界
點贊再看,養成習慣
給我來個Star吧,點選瞭解下基於SpringBoot的元件化介面服務落地解決方案

常見配置繫結方式

SpringBoot2.x基礎篇:談談SpringBoot內提供的這幾種配置繫結

SpringBoot在不斷地版本迭代中陸續提供了不同的配置引數繫結的方式,我們可以單獨獲取一個配置引數也可以將一系列的配置對映繫結到JavaBean的屬性欄位,下面我們來看看這幾種方式的配置繫結哪一種是你最常用到的。

示例配置引數

system:
  config:
    app-id: hengboy
    app-secret: yuqiyu@admin
複製程式碼

上面是一段示例的配置引數,提供給下面的配置繫結方式來使用。

@Configuration方式繫結

當我們需要將一個配置字首下的引數對映繫結到JavaBean的屬性欄位時,我們可以考慮使用@ConfigurationProperties + @Configuration註解組合的方式,使用如下所示:

/**
 * 系統配置
 *
 * @author 恆宇少年
 */
@Configuration
@ConfigurationProperties(prefix = SYSTEM_CONFIG_PREFIX)
@Data
public class SystemConfig {
    /**
     * 系統配置字首
     */
    public static final String SYSTEM_CONFIG_PREFIX = "system.config";

    private String appId;
    private String appSecret;
}
複製程式碼

**注意事項:**配置引數與JavaBean屬性之間的繫結是通過呼叫JavaBean屬性的Setter方法來賦值的,所以我們需要提供對應屬性欄位的Setter方法。

由於@Configuration註解被@Component修飾,所以我們在使用時只需要注入SystemConfig配置繫結對映類即可,通過Getter方法來獲取對應配置引數的值。

配置掃描路徑方式繫結

如果你係統中需要建立的配置對映類較多,而且每一個類都需要交付給IOC容器進行託管,那麼可以考慮使用@ConfigurationPropertiesScan + @ConfigurationProperties註解組合的方式,使用如下所示:

@SpringBootApplication
@ConfigurationPropertiesScan
public class ConfigureBindingAwayApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigureBindingAwayApplication.class, args);
    }
}
複製程式碼

我們首先需要在XxxApplication應用程式啟動類上新增@ConfigurationPropertiesScan註解,表示我們需要使用自動掃描的方式來註冊配置對映類,註解配置引數如下所示:

  • value:配置掃描的基礎package,與basePackages作用一致,通過陣列的形式來接收配置。
  • basePackages:配置掃描的基礎package
  • basePackageClasses:配置基礎掃描類,會將每一個掃描類所處於的package作為掃描基礎package

當我們在使用@ConfigurationPropertiesScan註解時,如果不進行自定義掃描路徑,預設使用SpringBoot應用程式掃描的packages

使用這種方式我們配置對映類就不再需要新增@Configuration註解了,這是因為我們在使用@ConfigurationPropertiesScan註解時,會通過@Import方式來引用配置對映類的註冊實現,詳見:org.springframework.boot.context.properties.ConfigurationPropertiesScanRegistrar#registerBeanDefinitions,配置對映類如下所示:

/**
 * 系統配置
 *
 * @author 恆宇少年
 */
@ConfigurationProperties(prefix = SYSTEM_CONFIG_PREFIX)
@Data
public class SystemConfig {
    /**
     * 系統配置字首
     */
    public static final String SYSTEM_CONFIG_PREFIX = "system.config";

    private String appId;
    private String appSecret;
}
複製程式碼

建構函式方式繫結

在上面的兩種方式都是通過Setter方法來進行對映欄位的賦值,而建構函式繫結方式是通過建構函式來進行賦值的,我們只需要在配置對映類上新增@ConstructorBinding註解並提供對應的建構函式即可,使用方式如下所示:

/**
 * 系統配置
 *
 * @author 恆宇少年
 */
@ConfigurationProperties(prefix = SYSTEM_CONFIG_PREFIX)
@ConstructorBinding
@Getter
public class SystemConfig {
    /**
     * 系統配置字首
     */
    public static final String SYSTEM_CONFIG_PREFIX = "system.config";

    public SystemConfig(String appId, String appSecret) {
        this.appId = appId;
        this.appSecret = appSecret;
    }

    private String appId;
    private String appSecret;
}
複製程式碼

在之前我也寫過一篇關於建構函式對映配置引數的問題,詳情訪問:@ConstructorBinding註解的使用

第三方類繫結

如果我們需要將配置引數對映繫結到第三方依賴內提供的JavaBean,我們該使用什麼方式呢?由於接收引數的類並不是我們自己編寫的,所以沒有辦法對.class檔案原始碼進行修改。

這時我們可以將第三方提供的JavaBean交給IOC容器託管,然後結合@ConfigurationProperties註解來對映繫結配置引數,使用方式如下所示:

@Bean
@ConfigurationProperties(prefix = SYSTEM_CONFIG_PREFIX)
public SystemConfig systemConfig() {
	return new SystemConfig();
}
複製程式碼

這種方式也需要第三方提供的JavaBean有對映欄位的Setter方法,否則無法進行賦值。

我們知道通過@Bean註解修飾的方法,會將方法的返回值加入到IOC容器內,那我們在使用配置時,直接注入配置對映類就可以了。

總結

上面這幾種配置繫結方式都遵循OOP實現,當然如果你只需要獲取一個配置引數,使用@Value也是一個好的選擇,沒有更好,只有更合適,根據每一種繫結方式的特點合理的選擇一個合適業務的方式。

SpringBoot2.x基礎篇:談談SpringBoot內提供的這幾種配置繫結

作者個人 部落格 使用開源框架 ApiBoot 助你成為Api介面服務架構師

相關文章