SpringBoot入門(五)——自定義配置


本文來自網易雲社區


大部分比薩店也提供某種形式的自動配置。你可以點葷比薩、素比薩、香辣意大利比薩,或者是自動配置比薩中的極品——至尊比薩。在下單時,你並沒有指定具體的輔料,你所點的比薩種類決定了所用的輔料。但如果你想要至尊比薩上的全部輔料,還想要加墨西哥胡椒,又不想放蘑菇該怎么辦?你偏愛辣食又不喜歡吃菌類,自動配置不適合你的口味,你就只能自己配置比薩了嗎?當然不是,大部分比薩店會讓你以菜單上已有的選項為基礎進行定制。


   

外化屬性

屬性源

為了使應用能適應不同的環境,SpringBoot支持外化配置。可以使用.properties文件、YAML文件、環境變量、命令行參數等方式。

SpringBoot能從多種屬性源獲得屬性,包括以下幾處:

  1. 命令行參數

  2. JVM系統屬性

  3. 操作系統環境變量

  4. 隨機生成的帶random.*前綴的屬性(在設置其他屬性時,可以引用它們,比如${random.long})

  5. 應用程序以外的application.properties或者application.yml文件

  6. 打包在應用程序內的application.properites或者application.yml文件

  7. 通過@propertySource標注的屬性源

  8. 默認屬性


優先級由高到低,即在上面的列表中“命令行參數”的優先級最高,會覆蓋下面其他屬性源的相同配置。

這里只挑選了部分比較常見的屬性源,詳細信息可以參考官網教程:24. Externalized Configuration

默認情況下SpringApplication將任何可選的命令行參數(以'--'開頭,比如,--server.port=9000)轉化為property,並將其添加到Spring Environment中。如上所述,命令行屬性總是優先於其他屬性源。

如果不想用這個特性可以用SpringApplication.setAddCommandLineProperties(false)來禁用。


YAML

SpringBoot支持YAML格式的配置文件文件后綴為yml,是一種更易讀寫的通用的數據串行化格式。

在SpringBoot中.yml效果相當於.properties,通常情況下二者是可以互相替換的,比如下面2種配置文件在SpringBoot中是等效的:

application.properties

server.port=8020
server.address=127.0.0.1

application.yml

server:  port: 8020  address: 127.0.0.1

.yml文件在配置數據的時候具有面向對象的特性,更易閱讀。

雖然.yml配置和.properties基本等效,但也有略微區別,.yml配置不能用@propertySource注解加載。  


Application屬性文件

SpringBoot會從以下位置加載.properties或.yml配置文件:

  1. 當前目錄下的/config目錄

  2. 當前目錄

  3. classpath下的/config目錄

  4. classpath的根目錄


優先級也是從高到低,高優先級的配置文件會覆蓋低優先級的配置。

使用.properties或.yml配置文件可以對SpringBoot的自動配置進行覆蓋,比如在默認的情況下http端口為8080,我們可以像上面的例子那樣在修改為8020。

SpringBoot提供了上百個這樣可以覆蓋的配置,具體可以查閱官網或者查看autoconfiguration包的的META-INF/spring-configuration-metadata.json和META-INF/additional-spring-configuration-metadata.json文件(這2個文件用來給IDE做輸入提示用,有一些簡單的描述)。


類型安全的配置屬性

有時候使用@Value("#{property}")注解注入配置會比較笨重,SpringBoot提供一個類型安全的方案,用強類型的Bean對象來替代屬性。

@ConfigurationProperties用法如下

@ConfigurationProperties(prefix = "acme")public class AcmeProperties {    private boolean enabled;    private final Security security = new Security();    // 省略getter、setter

    public static class Security {        private String username;        private String password;        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));        // 省略getter、setter
    }
}

@ConfigurationProperties的參數prefix表示前綴,AcmeProperties里的每個屬性的名稱便是具體的配置名。比如成員變量enabled綁定屬性acme.enabled。

上面這個例子表示AcmeProperties對象分別綁定下列屬性:

  • acme.ebalbe:布爾類型

  • acme.security.username:String類型

  • acme.security.pasword:String類型

  • acme.security.roles:類型是一個String集合


綁定配置之后還需要注冊Spring上下文中,有3種方式:


  1. 在java配置類中用@EnableConfigurationProperties注解激活

@Configuration@EnableConfigurationProperties(AcmeProperties.class)public class MyConfiguration {
}
  1. 直接在AcmeProperties加@Component注解


@Component@ConfigurationProperties(prefix="acme")public class AcmeProperties {    // ... see the preceding example}
  1. 在配置類中與@Bean注解組合


@Beanpublic AnotherComponent anotherComponent() {
    ...
}

注冊之后,可以在任意地方使用@Autowire注解注入使用。


松散的綁定(Relaxed binding)

Spring Boot使用一些寬松的規則用於綁定Environment屬性到@ConfigurationProperties beans,所以Environment屬性名和bean屬性名不需要精確匹配。常見的有虛線匹配大寫(比如,context-path綁定到contextPath)和將環境屬性轉為大寫字母(比如,PORT綁定port)。

比如:

@ConfigurationProperties(prefix="acme.my-project.person")public class OwnerProperties {    private String firstName;    // 省略getter、setter}

可以綁定到:

Property Note
acme.my-project.person.firstName 標准的駝峰式命名
acme.my-project.person.first-name 虛線表示,適用於.properties和.yml
acme.my-project.person.first_name 下划線表示,適用於.properties和.yml
ACME_MYPROJECT_PERSON_FIRSTNAME 大寫形式,適用於環境變量


@ConfigurationProperties vs @Value

Feature @ConfigurationProperties @Value
Relaxed binding Yes No
Meta-data support Yes No
SpEL evaluation No Yes


其他

查看當前生效的配置

SpringBoot默認提供了大量的自動配置,我們可以通過啟動時添加--debug參數來查看當前的配置信息。

激活的配置如下:

Positive matches:-----------------   CodecsAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.http.codec.CodecConfigurer'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)

   CodecsAutoConfiguration.JacksonCodecConfiguration matched:
      - @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)...

未激活的配置如下:

Negative matches:-----------------
   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)
   AopAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice', 'org.aspectj.weaver.AnnotatedElement' (OnClassCondition)
...

可以清楚的看到每個配置的條件,未激活的配置可以從這里直觀的看到原因。

debug可以用-Ddebug或--debug來啟用,也可以在.properties或.yml文件中配置debug的值為true。  


去除指定的自動配置

用@EnableAutoConfiguration注解的exclude參數去除指定的自動配置:

import org.springframework.boot.autoconfigure.*;import org.springframework.boot.autoconfigure.jdbc.*;import org.springframework.context.annotation.*;@Configuration@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})public class MyConfiguration {
}


小結

本節介紹了SpringBoot自定義配置的幾種方式。通過屬性外化,我們可以靈活選擇不同的屬性元來應對不同的場景。利用YAML可以讓配置文件結構化更易於閱讀,特別是有多層結構的屬性。@ConfigurationProperties提供類型安全的屬性使用方式,使用起來更加直觀。組合使用YAML和@ConfigurationProperties相信能讓項目的配置變得更加清晰。

SpringBoot不僅僅是幫助我們快速搭建一個可用的項目,在使用便利性上也提供了更多的姿勢。


 


相關閱讀:SpringBoot入門(一)——開箱即用

SpringBoot入門(二)——起步依賴

SpringBoot入門(三)——入口類解析

SpringBoot入門(四)——自動配置

SpringBoot入門(五)——自定義配置

       

網易雲新用戶大禮包:https://www.163yun.com/gift

 

本文來自網易實踐者社區,經作者金港生授權發布。



 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM