Spring Boot容許外化(externalize)你的配置,這樣你可以在不一樣的環境下使用相同的代碼。你可使用properties文件,YAML文件,環境變量和命令行參數來外化配置。使用@Value
註解,能夠直接將屬性值注入到你的beans中,並經過Spring的Environment
抽象或綁定到結構化對象來訪問。
Spring Boot使用PropertySource
次序來容許對值進行合理的覆蓋,須要如下面的次序考慮屬性:java
java:comp/env
的JNDI屬性System.getProperties()
)RandomValuePropertySource
@Configuration
類上的@PropertySource
註解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
SpringApplication將從如下位置加載application.properties
文件,並把它們添加到Spring Environment中:dom
/config
子目錄/config
包這個列表是按優先級排序的(列表中位置高的將覆蓋位置低的)。編輯器
注:你可使用YAML(
.yml
)文件替代.properties
。ide
若是不喜歡將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上下文初始化參數能夠用來取代環境變量或系統屬性,固然也可使用環境變量或系統屬性。
除了application.properties
文件,特定配置屬性也能經過命令慣例application-{profile}.properties
來定義。特定Profile屬性從跟標準application.properties
相同的路徑加載,而且特定profile文件會覆蓋默認的配置。
在多環境下,使用特定的屬性application-{profile}.properties
區別不一樣的運行環境。例如:
application-dev.properties
:開發環境application-test.properties
:測試環境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
替代。
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文件。
你能夠在單個文件中定義多個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。
使用@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)。
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。