springboot yml中不寫會從環境變數取值嗎_Spring Boot從入門到實戰:Spring Boot自定義屬性...
技術標籤:springboot yml中不寫會從環境變數取值嗎
Web專案開發中,經常需要自定義一些屬性,如資料庫連線,第三方服務介面地址,第三方服務的appKey、appSecret等,以及針對不同環境,這些屬性的值還需要有相應的調整,如開發環境、測試環境、生產環境所用資料庫不同,則針對不同環境的同一屬性需要配置不同的值。
傳統自定義屬性配置及訪問
在傳統的Spring Web應用中,自定義屬性一般是通過在類路徑中(如resources目錄)新增一個類似my.properties配置檔案(檔名自定義),然後在xml配置中通過
引入屬性檔案。再定義一個Bean來讀取這些屬性,Bean配置:
Bean定義:
public class MyPropertiesUtil { private static Properties properties; public static void init(Properties props) { properties = props; } public static String getValue(String key) { return properties.getProperty(key); }}
在其它需要訪問的地方通過 MyPropertiesUtil.getValue() 方法來訪問具體某個屬性的值。
Spring Boot自定義屬性配置及優先順序
在Spring Boot中,可以在多個地方配置屬性,包括.properties檔案,.yaml檔案,環境變數, 系統屬性,命令列引數等, 這些屬性都會被Spring Boot載入到Environment中,可通過@Value註解,Environment例項,或 @ConfigurationProperties註解的類來訪問。
屬性載入優先順序順序:
- 如果有使用devtools,devtools 全域性設定的屬性(使用者目錄 ~/.spring-bootdevtools.properties)
- 測試類的註解@TestPropertySource
- 測試類註解 @SpringBootTest#properties 配置的屬性
- 命令列引數
- SPRING_APPLICATION_JSON裡的屬性(環境變數或系統屬性)
- ServletConfig初始化引數
- ServletContext初始化引數
- JNDI引數 java:comp/env
- Java系統屬性 System.getProperties()
- 作業系統環境變數
- RandomValuePropertySource 配置的屬性 random.*
- jar包外部的applictaion-{profile}.properties,applictaion-{profile}.yml配置檔案
- jar包內部的applictaion-{profile}.properties,applictaion-{profile}.yml配置檔案
- jar包外部的applictaion.properties,applictaion.yml配置檔案
- jar包內部的applictaion.properties,applictaion.yml配置檔案
- @Configuration類上的 @PropertySource註解指定的配置檔案
- 預設屬性: SpringApplication.setDefaultProperties
上述屬性配置,除了粗體標註的外,其它一般應用較少。序號低的配置優先順序高於序號高的配置,即如果存在相同屬性配置 ,則序號低的配置會覆蓋序號高的配置。applictaion-{profile}.properties 一般用於具體某個環境特有的屬性配置,如application-dev.properties用於開發環境,可通過 spring.profiles.active=dev指定載入dev環境配置
常用屬性配置方式
- 命令列引數
- 啟動Spring Boot應用時,可以指定命令列引數,如:
java -jar springboot-properties.jar [email protected]_line
該引數值將會覆蓋應用在其它地方配置的同名屬性值。命令列引數放在xx.jar 的後面。
可以通過SpringApplication.setAddCommandLineProperties(false) 禁用命令列引數配置
- Java系統屬性
- 同樣在啟動Spring Boot應用時,可以指定Java系統屬性,一般見於自定義jvm引數,如:
java [email protected]_properties -jar springboot-properties.jar
Java系統屬性放在java命令之後。
- 作業系統環境變數(實際應用其實較少)
- 配置過JAVA_HOME的應該理解何為環境變數。某些作業系統可能不支援.分隔的屬性名,可以改為以下劃線連線。Spring Boot將myName, my.name, MY_NAME視為等效。
- 應用屬性配置檔案(.properties檔案或 .yml檔案)
- .properties檔案屬性配置格式:
my.name=jboostmy.list[0]=aaa //配置列表my.list[1]=bbb
.yml檔案屬性配置格式:
my: name: devlink list: //配置列表 - aaa - bbb
yml中,屬性名與值之間冒號後面必須有空格。
應用屬性配置檔案位置:
- jar包所在當前目錄下的子目錄/config(外接屬性檔案)
- jar包所在當前目錄(外接屬性檔案)
- classpath根目錄下的子目錄/config(內建屬性檔案)
- classpath根目錄(內建屬性檔案)
序號低的優先順序高於序號高的優先順序,即jar包外的配置優先順序高於jar包內的配置。同一目錄下,.properties檔案的優先順序高於.yml檔案。application-{profile}.properties的優先順序高於application.properties。
Spring Boot自定義屬性訪問方式
- 類中屬性上新增 @Value(“${xx}”) 註解方式。如:
@Value("${my.name}")private String name;
可以指定預設值,如 @Value(“${my.name:jboost}”), 當my.name未配置時,預設使用值”jboost”
- 通過@ConfigurationProperties註解的類來訪問。如定義:
@[email protected](prefix = "my")public class MyConfigProperties { private String name; private String website; //省略了getter、setter函式}
然後在需要訪問的Bean中,通過@Autowired 注入MyConfigProperties例項,通過getName()方法即可訪問my.name屬性值。
@Autowiredprivate MyConfigProperties myConfigProperties;@Testpublic void testConfigurationProperties(){ System.out.println("test @ConfigurationProperties =========="); System.out.println(myConfigProperties.getName()); System.out.println(myConfigProperties.getWebsite());}
- 通過Environment 例項訪問。如:
@Autowiredprivate Environment env;@Testpublic void testEnvironment(){ System.out.println("test Environment =========="); System.out.println(env.getProperty("my.name")); System.out.println(env.getProperty("my.website