在Spring Boot中多環(huán)境配置文件名需要滿足application-{profile}.properties的格式抗楔,其中{profile}對(duì)應(yīng)你的環(huán)境標(biāo)識(shí)产徊,如:
application-dev.properties:開發(fā)環(huán)境
application-pro.properties:生產(chǎn)環(huán)境
這樣就可以使用多狀態(tài)配置。在使用時(shí),需要在配置文件application.properties中標(biāo)記激活配置spring.profiles.active=dec
命令行 執(zhí)行java -jar xxx.jar --spring.profiles.active=dev,就可以使用application-dev.properties中的配置。
比如在Test中,加入:@ActiveProfiles("dev")即可使用dev的配置缎谷。加入:@ActiveProfiles("home")即可使用home的配置。
配置文件也可以寫成application.yml灶似,格式更簡潔列林。
如開發(fā)環(huán)境和生產(chǎn)環(huán)境分開配置,可以使用符號(hào)---酪惭,如:
spring:
? profiles:
#激活開發(fā)環(huán)境
? ? active: dev
---
#開發(fā)環(huán)境配置
spring:
? profiles: dev
server:
port:8080
---
#生產(chǎn)環(huán)境配置
spring:
? profiles: pro
server:
port:8082
注意希痴,參數(shù)值和:之間要有空格
在類中使用配置里的值,可以使用@Value注解:
@value("${age}")
privateInteger age;
在類前注釋 @ConfigurationProperties 可以直接為類的屬性賦值為配置參數(shù)撞蚕,
‘prefix’是配置前綴
首先增加配置參數(shù)文件user.yml:
profile:
age: 20
sex: 1
nickname: jack
使用配置屬性:
@Component
@ConfigurationProperties(prefix ="user")
@PropertySource("classpath:profile.yml")
publicclassUserConfiguration{
privateString sex;
privateString nickname;
? ? ...
}
@PropertySource 指定配置文件路徑
命令:java -jar xxx.jar --server.port=8888润梯,通過使用--server.port屬性來設(shè)置xxx.jar應(yīng)用的端口為8888。
在命令行運(yùn)行時(shí),連續(xù)的兩個(gè)減號(hào)--就是對(duì)application.properties中的屬性值進(jìn)行賦值的標(biāo)識(shí)纺铭。所以寇钉,java -jar xxx.jar --server.port=8888命令,等價(jià)于我們?cè)赼pplication.properties中添加屬性server.port=8888舶赔,該設(shè)置在樣例工程中可見扫倡,讀者可通過刪除該值或使用命令行來設(shè)置該值來驗(yàn)證。
安全起見竟纳,Spring Boot提供了屏蔽命令行訪問屬性的設(shè)置撵溃,只需要這句設(shè)置就能屏蔽:SpringApplication.setAddCommandLineProperties(false)。
配置優(yōu)先級(jí)
優(yōu)先級(jí)如下:
命令行參數(shù)
來自java:comp/env的JNDI屬性
Java系統(tǒng)屬性(System.getProperties())
操作系統(tǒng)環(huán)境變量
RandomValuePropertySource配置的random.*屬性值
jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
jar包內(nèi)部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
jar包外部的application.properties或application.yml(不帶spring.profile)配置文件
jar包內(nèi)部的application.properties或application.yml(不帶spring.profile)配置文件
@Configuration注解類上的@PropertySource
通過SpringApplication.setDefaultProperties指定的默認(rèn)屬性
application.properties和application.yml的區(qū)別是
一般我們的application.properties文件內(nèi)容是:
server.port=8090
server.session-timeout=30
server.context-path=
server.tomcat.max-threads=0
server.tomcat.uri-encoding=UTF-8
spring.datasource.url = jdbc:mysql://localhost:3306/newbirds
spring.datasource.username = root
spring.datasource.password = mymysql
spring.datasource.driverClassName = com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not logforeach sql query
spring.jpa.show-sql =true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
而官方給的很多demo锥累,都是用yml文件配置的缘挑。
yml文件的好處,天然的樹狀結(jié)構(gòu)桶略,一目了然语淘。不過當(dāng)時(shí)把a(bǔ)pplication.properties 改成?application.yml還是痛苦了一會(huì)兒。
server:
port:8090
session-timeout:30
tomcat.max-threads:0
tomcat.uri-encoding: UTF-8
spring:
? datasource:
url : jdbc:mysql://localhost:3306/newbirds
? ? username : root
? ? password : mymysql
? ? driverClassName : com.mysql.jdbc.Driver
? jpa:
? ? database : MYSQL
show-sql :true
? ? hibernate:
? ? ? ddl-auto : update
? ? ? naming-strategy : org.hibernate.cfg.ImprovedNamingStrategy
? ? properties:
? ? ? hibernate:
? ? ? ? dialect : org.hibernate.dialect.MySQL5Dialect
注意點(diǎn):
1际歼,原有的key惶翻,例如spring.jpa.properties.hibernate.dialect,按“.”分割鹅心,都變成樹狀的配置
2吕粗,key后面的冒號(hào),后面一定要跟一個(gè)空格
3旭愧,把原有的application.properties刪掉颅筋。然后一定要執(zhí)行一下 ?maven -X clean install
您可以使用spring.profiles鍵指定文檔何時(shí)適用,在單個(gè)文件中指定多個(gè)特定于配置文件的YAML文檔?输枯,如以下示例所示:
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production & eu-central
server:
address: 192.168.1.120
在前面的示例中垃沦,如果development配置文件處于活動(dòng)狀態(tài),則server.address屬性為127.0.0.1用押。同樣,如果production和eu-central配置文件處于活動(dòng)狀態(tài)靶剑,則server.address屬性為192.168.1.120蜻拨。如果development,production并eu-central在配置文件沒有啟用桩引,那么該屬性的值192.168.1.100缎讼。
spring.profiles因此可以包含簡單的配置文件名稱(例如production)或配置文件表達(dá)式。例如坑匠,簡檔表達(dá)式允許表達(dá)更復(fù)雜的簡檔邏輯production & (eu-central | eu-west)血崭。有關(guān)詳細(xì)信息,請(qǐng)查閱參考指南。
如果在應(yīng)用程序上下文啟動(dòng)時(shí)沒有顯式激活夹纫,則激活默認(rèn)配置文件咽瓷。因此,在以下YAML中舰讹,我們?cè)O(shè)置的值僅在“默認(rèn)”配置文件中spring.security.user.password可用:
server:
? port: 8000
---
spring:
? profiles: default
? security:
? ? user:
? ? ? password: weak
然而茅姜,在以下示例中,始終設(shè)置密碼月匣,因?yàn)樗锤郊拥饺魏闻渲梦募耆鳎⑶冶仨氃诒匾獣r(shí)在所有其他配置文件中顯式重置:
server:
? port: 8000
spring:
? security:
? ? user:
? ? ? password: weak
通過使用該spring.profiles元素指定的彈簧輪廓可以任選地通過使用該!角色來否定。如果為單個(gè)文檔指定了否定和非否定的配置文件锄开,則至少一個(gè)非否定的配置文件必須匹配素标,并且沒有否定的配置文件可以匹配。
使用@PropertySource注釋無法加載YAML文件萍悴。因此头遭,如果您需要以這種方式加載值,則需要使用屬性文件退腥。
使用@Value("${property}")注釋注入配置屬性有時(shí)會(huì)很麻煩任岸,尤其是在使用多個(gè)屬性或數(shù)據(jù)本質(zhì)上是分層的情況下。Spring Boot提供了一種使用屬性的替代方法狡刘,該方法允許強(qiáng)類型bean管理和驗(yàn)證應(yīng)用程序的配置享潜,如以下示例所示:
package com.example;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("acme")
public class AcmeProperties {
private boolean enabled;
private InetAddress remoteAddress;
private final Security security = new Security();
public boolean isEnabled() { ... }
public void setEnabled(boolean enabled) { ... }
public InetAddress getRemoteAddress() { ... }
public void setRemoteAddress(InetAddress remoteAddress) { ... }
public Security getSecurity() { ... }
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
public String getUsername() { ... }
public void setUsername(String username) { ... }
public String getPassword() { ... }
public void setPassword(String password) { ... }
public List<String> getRoles() { ... }
public void setRoles(List<String> roles) { ... }
}
}
前面的POJO定義了以下屬性:
acme.enabled,false默認(rèn)值為嗅蔬。
acme.remote-address剑按,具有可以強(qiáng)制的類型String。
acme.security.username澜术,帶有嵌套的“安全”對(duì)象艺蝴,其名稱由屬性名稱決定。特別是鸟废,那里根本沒有使用返回類型SecurityProperties猜敢。
acme.security.password。
acme.security.roles,收集String。
getter和setter通常是必需的糯俗,因?yàn)榻壎ㄊ峭ㄟ^標(biāo)準(zhǔn)的Java Beans屬性描述符铜异,就像在Spring MVC中一樣。在下列情況下可以省略setter:
映射,只要它們被初始化,就需要一個(gè)getter但不一定是setter,因?yàn)樗鼈兛梢员唤壎ㄆ髯儺悺?/p>
可以通過索引(通常使用YAML)或使用單個(gè)逗號(hào)分隔值(屬性)訪問集合和數(shù)組博脑。在后一種情況下憎乙,必須使用setter。我們建議始終為此類型添加setter叉趣。如果初始化集合泞边,請(qǐng)確保它不是不可變的(如上例所示)。
如果初始化嵌套的POJO屬性(如Security前面示例中的字段)君账,則不需要setter繁堡。如果您希望綁定器通過使用其默認(rèn)構(gòu)造函數(shù)動(dòng)態(tài)創(chuàng)建實(shí)例,則需要一個(gè)setter乡数。
有些人使用Project Lombok自動(dòng)添加getter和setter椭蹄。確保Lombok不為此類型生成任何特定構(gòu)造函數(shù),因?yàn)槿萜鲿?huì)自動(dòng)使用它來實(shí)例化對(duì)象净赴。
最后绳矩,僅考慮標(biāo)準(zhǔn)Java Bean屬性,并且不支持對(duì)靜態(tài)屬性的綁定玖翅。
另見?和之間@Value@ConfigurationProperties的差異翼馆。
您還需要列出要在@EnableConfigurationProperties注釋中注冊(cè)的屬性類?,如以下示例所示:
@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}
當(dāng)@ConfigurationPropertiesbean以這種方式注冊(cè)時(shí)金度,bean具有常規(guī)名稱:<prefix>-<fqn>应媚,其中<prefix>是@ConfigurationProperties注釋中指定的環(huán)境鍵前綴,并且<fqn>是bean的完全限定名稱猜极。如果注釋未提供任何前綴中姜,則僅使用bean的完全限定名稱。
上面示例中的bean名稱是acme-com.example.AcmeProperties跟伏。
即使前面的配置創(chuàng)建了一個(gè)常規(guī)beanAcmeProperties丢胚,我們也建議@ConfigurationProperties只處理環(huán)境,特別是不要從上下文中注入其他bean受扳。話雖如此携龟,@EnableConfigurationProperties注釋也會(huì)自動(dòng)應(yīng)用于您的項(xiàng)目,以便從中配置任何注釋的現(xiàn)有bean?勘高。您可以通過確保?已經(jīng)是bean?來快捷方式峡蟋,如以下示例所示:@ConfigurationPropertiesEnvironmentMyConfigurationAcmeProperties
@Component
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {
// ... see the preceding example
}
這種配置方式與SpringApplication外部YAML配置特別有效,如以下示例所示:
# application.yml
acme:
remote-address: 192.168.1.1
security:
username: admin
roles:
? - USER
? - ADMIN
#根據(jù)需要進(jìn)行額外配置
要使用@ConfigurationPropertiesbean华望,您可以使用與任何其他bean相同的方式注入它們层亿,如以下示例所示:
@Service
public class MyService {
private final AcmeProperties properties;
@Autowired
public MyService(AcmeProperties properties) {
? ? this.properties = properties;
}
//...
@PostConstruct
public void openConnection() {
Server server = new Server(this.properties.getRemoteAddress());
// ...
}
}
使用@ConfigurationProperties還可以生成元數(shù)據(jù)文件,IDE可以使用這些文件為您自己的密鑰提供自動(dòng)完成功能立美。有關(guān)詳細(xì)信息,請(qǐng)參閱附錄B方灾,配置元數(shù)據(jù)附錄建蹄。
除了@ConfigurationProperties用于注釋類之外碌更,您還可以在公共@Bean方法上使用它。當(dāng)您想要將屬性綁定到控件之外的第三方組件時(shí)洞慎,這樣做會(huì)特別有用痛单。
要從Environment屬性配置bean?,請(qǐng)?zhí)砑覢ConfigurationProperties到其bean注冊(cè)劲腿,如以下示例所示:
@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
...
}
使用another前綴定義的任何屬性都AnotherComponent以與前面AcmeProperties示例類似的方式映射到該bean?旭绒。
Spring Boot使用一些寬松的規(guī)則來綁定bean的Environment屬性@ConfigurationProperties,因此不需要在Environment屬性名和bean屬性名之間進(jìn)行精確匹配?焦人。這有用的常見示例包括破折號(hào)分隔的環(huán)境屬性(例如挥吵,context-path綁定到contextPath)和大寫環(huán)境屬性(例如,PORT綁定到port)花椭。
例如忽匈,請(qǐng)考慮以下@ConfigurationProperties類:
@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {
private String firstName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
在前面的示例中,可以使用以下屬性名稱:
表24.1矿辽。輕松綁定
屬性注意
acme.my-project.person.first-name烤肉串案例丹允,建議用于.properties和.yml文件。
acme.myProject.person.firstName標(biāo)準(zhǔn)的駝峰案例語法袋倔。
acme.my_project.person.first_name下劃線表示法雕蔽,它是用于.properties和.yml文件的替代格式。
ACME_MYPROJECT_PERSON_FIRSTNAME大寫格式宾娜,使用系統(tǒng)環(huán)境變量時(shí)建議使用批狐。
prefix注釋的值必須是kebab大小寫(小寫并且用-,例如acme.my-project.person)碳默。
表24.2贾陷。每個(gè)屬性源放寬綁定規(guī)則
物業(yè)來源簡單名單
屬性文件駱駝案,烤肉串案例或下劃線表示法標(biāo)準(zhǔn)列表語法使用[ ]或逗號(hào)分隔值
YAML文件駱駝案嘱根,烤肉串案例或下劃線表示法標(biāo)準(zhǔn)YAML列表語法或逗號(hào)分隔值
環(huán)境變量大寫格式髓废,下劃線作為分隔符。_不應(yīng)在屬性名稱中使用由下劃線包圍的數(shù)字值该抒,例如MY_ACME_1_OTHER = my.acme[1].other
系統(tǒng)屬性駱駝案慌洪,烤肉串案例或下劃線表示法標(biāo)準(zhǔn)列表語法使用[ ]或逗號(hào)分隔值
我們建議,在可能的情況下凑保,屬性以小寫的kebab格式存儲(chǔ)冈爹,例如my.property-name=acme。
綁定到Map屬性時(shí)欧引,如果key包含除小寫字母數(shù)字字符以外的任何內(nèi)容频伤,則-需要使用括號(hào)表示法以保留原始值。如果密鑰未被包圍[]芝此,則任何非字母數(shù)字或-刪除的字符憋肖。例如因痛,考慮將以下屬性綁定到Map:
acme:
? map:
? ? "[/key1]": value1
? ? "[/key2]": value2
? ? /key3: value3
上面的屬性將綁定到Mapwith/key1,/key2并key3作為地圖中的鍵岸更。
當(dāng)列表在多個(gè)位置配置時(shí)鸵膏,覆蓋通過替換整個(gè)列表來工作。
例如怎炊,假設(shè)一個(gè)MyPojo具有對(duì)象name和description那些屬性null默認(rèn)谭企。以下示例公開了以下MyPojo對(duì)象?列表AcmeProperties:
@ConfigurationProperties("acme")
public class AcmeProperties {
private final List<MyPojo> list = new ArrayList<>();
public List<MyPojo> getList() {
return this.list;
}
}
請(qǐng)考慮以下配置:
acme:
? list:
? ? - name: my name
? ? ? description: my description
---
spring:
? profiles: dev
acme:
? list:
? ? - name: my another name
如果dev配置文件未激活,則AcmeProperties.list包含一個(gè)MyPojo條目评肆,如先前定義的那樣债查。dev但是,如果啟用了配置文件糟港,則list仍然只包含一個(gè)條目(名稱my another name和描述null)攀操。此配置不會(huì)MyPojo向列表添加第二個(gè)實(shí)例,也不會(huì)合并項(xiàng)目秸抚。
當(dāng)List在多個(gè)配置文件中指定a時(shí)速和,將使用具有最高優(yōu)先級(jí)(并且僅具有該優(yōu)先級(jí))的配置文件。請(qǐng)考慮以下示例:
acme:
? list:
? ? - name: my name
? ? ? description: my description
? ? - name: another name
? ? ? description: another description
---
spring:
? profiles: dev
acme:
? list:
? ? - name: my another name
在前面的示例中剥汤,如果dev配置文件處于活動(dòng)狀態(tài)颠放,則AcmeProperties.list包含一個(gè)MyPojo條目(名稱my another name和描述null)。對(duì)于YAML吭敢,逗號(hào)分隔列表和YAML列表都可用于完全覆蓋列表的內(nèi)容碰凶。
對(duì)于Map屬性,您可以綁定從多個(gè)源中提取的屬性值鹿驼。但是欲低,對(duì)于多個(gè)源中的相同屬性,使用具有最高優(yōu)先級(jí)的屬性畜晰。以下示例公開了一個(gè)Map<String, MyPojo>fromAcmeProperties:
@ConfigurationProperties("acme")
public class AcmeProperties {
private final Map<String, MyPojo> map = new HashMap<>();
public Map<String, MyPojo> getMap() {
return this.map;
}
}
請(qǐng)考慮以下配置:
acme:
? map:
? ? key1:
? ? ? name: my name 1
? ? ? description: my description 1
---
spring:
? profiles: dev
acme:
? map:
? ? key1:
? ? ? name: dev name 1
? ? key2:
? ? ? name: dev name 2
? ? ? description: dev description 2
如果dev配置文件未激活砾莱,則AcmeProperties.map包含一個(gè)帶密鑰的條目key1(名稱my name 1和描述my description 1)。dev但是凄鼻,如果啟用了配置文件腊瑟,則map包含兩個(gè)帶有鍵的條目key1(名稱dev name 1和描述my description 1)和key2(名稱dev name 2和描述dev description 2)。
參考:https://blog.csdn.net/yihui823/article/details/51836880
感興趣如下文章块蚌,會(huì)有幫助