spring boot 與配置

Spring Boot容許外化(externalize)你的配置,這樣你可以在不一樣的環境下使用相同的代碼。你可使用properties文件YAML文件環境變量命令行參數來外化配置。使用@Value註解,能夠直接將屬性值注入到你的beans中,並經過Spring的Environment抽象或綁定到結構化對象來訪問。
Spring Boot使用PropertySource次序來容許對值進行合理的覆蓋,須要如下面的次序考慮屬性:java

  1. 命令行參數
  2. 來自於java:comp/env的JNDI屬性
  3. Java系統屬性(System.getProperties()
  4. 操做系統環境變量只有在random.*裏包含的屬性會產生一個RandomValuePropertySource
  5. 在打包的jar外的應用程序配置文件(application.properties,包含YAML和profile變量)
  6. 在打包的jar內的應用程序配置文件(application.properties,包含YAML和profile變量)
  7. @Configuration類上的@PropertySource註解
  8. 默認屬性(使用SpringApplication.setDefaultProperties指定)

例如:spring

import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*

@Component
public class MyBean {
    @Value("${name}")
    private String name;
    // ...
}

你能夠將一個application.properties文件捆綁到jar內,用來提供一個合理的默認name屬性值。
當運行在生產環境時,能夠在jar外提供一個application.properties文件來覆蓋name屬性。
對於一次性的測試,你可使用特定的命令行開關啓動(好比,java -jar app.jar --name="Spring")。shell

默認狀況下,SpringApplication將任何可選的命令行參數(以'--'開頭,好比,--server.port=9000)轉化爲property,並將其添加到Spring Environment中。如上所述,命令行屬性老是優先於其餘屬性源
若是你不想將命令行屬性添加到Environment裏,你可使用SpringApplication.setAddCommandLineProperties(false)來禁止它們。安全

注意:在命令行添加的參數會添加到Spring Environment。app

配置隨機值

RandomValuePropertySource在注入隨機值(好比,密鑰或測試用例)時頗有用。它能產生整數,longs或字符串,好比:框架

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

random.int*語法是OPEN value (,max) CLOSE,此處OPEN,CLOSE能夠是任何字符,而且value,max是整數。若是提供max,那麼value是最小的值,max是最大的值(不包含在內)。less

Application屬性

SpringApplication將從如下位置加載application.properties文件,並把它們添加到Spring Environment中:dom

  1. 當前目錄下的一個/config子目錄
  2. 當前目錄
  3. 一個classpath下的/config
  4. classpath根路徑(root)

這個列表是按優先級排序的(列表中位置高的將覆蓋位置低的)。編輯器

注:你可使用YAML(.yml)文件替代.propertieside

若是不喜歡將application.properties做爲配置文件名,你能夠經過指定spring.config.name環境屬性來切換其餘的名稱。你也可使用spring.config.location環境屬性來引用一個明確的路徑(目錄位置或文件路徑列表以逗號分割)。

$ java -jar myproject.jar --spring.config.name=myproject
//or
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

若是spring.config.location包含目錄(相對於文件),那它們應該以/結尾(在加載前,spring.config.name產生的名稱將被追加到後面)。即此時使用的是spring.config.location+spring.config.name文件做爲默認加載文件。

無論spring.config.location是什麼值,默認的搜索路徑classpath:,classpath:/config,file:,file:config/總會被使用。以這種方式,你能夠在application.properties中爲應用設置默認值,而後在運行的時候使用不一樣的文件覆蓋它,同時保留默認配置。

注:若是你使用環境變量而不是系統配置,大多數操做系統不容許以句號分割(period-separated)的key名稱,但你可使用下劃線(underscores)代替(好比,使用SPRING_CONFIG_NAME代替spring.config.name)。若是你的應用運行在一個容器中,那麼JNDI屬性(java:comp/env)或servlet上下文初始化參數能夠用來取代環境變量或系統屬性,固然也可使用環境變量或系統屬性。

特定的profile

除了application.properties文件,特定配置屬性也能經過命令慣例application-{profile}.properties來定義。特定Profile屬性從跟標準application.properties相同的路徑加載,而且特定profile文件會覆蓋默認的配置。

在多環境下,使用特定的屬性application-{profile}.properties區別不一樣的運行環境。例如:

  1. application-dev.properties:開發環境
  2. application-test.properties:測試環境
  3. application-prod.properties:生產環境

至於哪一個具體的配置文件會被加載,須要在application.properties文件中經過spring.profiles.active屬性來設置,其值對應{profile}值,會加載對應的application-{profile}.properties屬性文件。例如在application.properties中設置spring.profiles.active=dev,那麼就會加載application-dev.properties做爲運行屬性。

因爲命令行屬性可覆蓋其餘狀況下設置的屬性,因此使用java -jar jarname.jar --spring.profiles.active=prod會覆蓋application.properties中設置的spring.profiles.active=dev,會加載application-prod.properties做爲運行時屬性。

因此,通常在application.properties中設置spring.profiles.active=dev,在線上環境使用命令行配置的方式覆蓋profile設置

佔位符語法

application.properties裏的值被使用時,它們會被存在的Environment過濾,因此你可以引用先前定義的值(好比,系統屬性)。

app.name=MyApp
app.description=${app.name} is a Spring Boot application

上述設置中app.description中的值${app.name},會被以前設置的app.name=MyApp替代。

使用YAML替代properties文件

Spring框架提供兩個便利的類用於加載YAML文檔,YamlPropertiesFactoryBean會將YAML做爲Properties來加載,YamlMapFactoryBean會將YAML做爲Map來加載。

示例:

environments:
    dev:
        url: http://dev.bar.com
        name: Developer Setup
    prod:
        url: http://foo.bar.com
        name: My Cool App

上面的YAML文檔會被轉化到下面的屬性中:

environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App

YAML列表被表示成使用[index]間接引用做爲屬性keys的形式,例以下面的YAML:

my:
   servers:
       - dev.bar.com
       - foo.bar.com

將會轉化到下面的屬性中:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

使用Spring DataBinder工具綁定屬性(這是@ConfigurationProperties作的事),你須要肯定目標bean中有個java.util.List或Set類型的屬性,而且須要提供一個setter或使用可變的值初始化它,好比,下面的代碼將綁定上面的屬性:

@ConfigurationProperties(prefix="my")
public class Config {
    private List<String> servers = new ArrayList<String>();
    public List<String> getServers() {
        return this.servers;
    }
}

加載

YamlPropertySourceLoader類可以用於將YAML做爲一個PropertySource導出到Sprig Environment。這容許你使用熟悉的@Value註解和佔位符語法訪問YAML屬性。

YAML文件不能經過@PropertySource註解加載。因此,在這種狀況下,若是須要使用@PropertySource註解的方式加載值,那就要使用properties文件。

multi-profiles YAML文檔

你能夠在單個文件中定義多個profile配置(profile-specific)的YAML文檔,並經過一個spring.profiles key標示應用的文檔。例如:

server:
    address: 192.168.1.100
---
spring:
    profiles: development
server:
    address: 127.0.0.1
---
spring:
    profiles: production
server:
    address: 192.168.1.120

在上面的例子中,若是development配置被激活,那server.address屬性將是127.0.0.1。若是development和production配置(profiles)沒有啓用,則該屬性的值將是192.168.1.100。

類型安全的配置屬性-ConfigurationProperties註解

使用@Value("${property}")註解注入配置屬性有時可能比較笨重,特別是須要使用多個properties或你的數據自己有層次結構。爲了控制和校驗你的應用配置,Spring Boot提供一個容許強類型beans的替代方法來使用properties。

示例:

你能夠經過在@EnableConfigurationProperties註解中直接簡單的列出屬性類來快捷的註冊@ConfigurationProperties bean的定義。

@Configuration
@EnableConfigurationProperties(ConnectionSettings.class)
public class MyConfiguration {
}
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
    private String username;
    private InetAddress remoteAddress;
    // ... getters and setters
}

@EnableConfigurationProperties註解應用到你的@Configuration時,任何被@ConfigurationProperties註解的beans將自動被Environment屬性配置。這種風格的配置特別適合與SpringApplication的外部YAML配置進行配合使用。

# application.yml
connection:
    username: admin
    remoteAddress: 192.168.1.1
# additional configuration as required

使用:爲了使用@ConfigurationProperties beans,你可使用與其餘任何bean相同的方式注入它們。

@Service
public class MyService {
    @Autowired
    private ConnectionSettings connection;
     //...
    @PostConstruct
    public void openConnection() {
        Server server = new Server();
        this.connection.configure(server);
    }
}

第三方類屬性設置

@ConfigurationProperties能夠方便的設置第三方類的屬性,該註解由spring-boot-configuration-processor提供。

爲了從Environment屬性配置一個bean,將@ConfigurationProperties添加到它的bean註冊過程:

@ConfigurationProperties(prefix = "foo")
@Bean
public FooComponent fooComponent() {
    ...
}

和上面ConnectionSettings的示例方式相同,任何以foo爲前綴的屬性定義都會被映射到FooComponent上。

注: 能夠在帶有@Component的類或者@bean等,定義bean的時候使用@ConfigurationProperties註解,自動從Spring Environment 獲取相關的屬性。

鬆散類型

Spring Boot使用一些寬鬆的規則用於綁定Environment屬性到@ConfigurationProperties beans,因此Environment屬性名和bean屬性名不須要精確匹配。常見的示例中有用的包括虛線分割(好比,context--path綁定到contextPath)和將環境屬性轉爲大寫字母(好比,PORT綁定port)。
示例:

@Component
@ConfigurationProperties(prefix="person")
public class ConnectionSettings {
    private String firstName;
}

下面的屬性名都能用於上面的@ConfigurationProperties類:

屬性 說明
person.firstName 標準駝峯規則
person.first-name 虛線表示,推薦用於.properties和.yml文件
PERSON_FIRST_NAME 大寫形式,使用系統環境變量時推薦

Spring會嘗試強制外部的應用屬性在綁定到@ConfigurationProperties beans時類型是正確的。若是須要自定義類型轉換,你能夠提供一個ConversionService bean(bean id爲conversionService)或自定義屬性編輯器(經過一個CustomEditorConfigurer bean)。

@ConfigurationProperties校驗

Spring Boot將嘗試校驗外部的配置,默認使用JSR-303(若是在classpath路徑中)。你能夠輕鬆的爲你的@ConfigurationProperties類添加JSR-303 javax.validation約束註解:

@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
    @NotNull
    private InetAddress remoteAddress;
    // ... getters and setters
}

你也能夠經過建立一個叫作configurationPropertiesValidator的bean來添加自定義的Spring Validator。

相關文章
相關標籤/搜索