從組態檔中獲取屬性應該是SpringBoot開發中最為常用的功能之一,但就是這麼常用的功能,仍然有很多開發者抓狂~今天帶大家簡單回顧一下這六種的使用方式:
說明 | |
---|---|
Environment物件 | Environment 是 springboot 核心的環境設定介面,它提供了簡單的方法來存取應用程式屬性,包括系統屬性、作業系統環境變數、命令列引數、和應用程式組態檔中定義的屬性等等,使用 Environment 方式來獲取設定屬性值非常簡單,只要注入Environment類呼叫其方法**getProperty(屬性key)**即可 |
@Value | @Value註解是Spring框架提供的用於注入設定屬性值的註解,它可用於類的成員變數、方法引數和建構函式引數上, 在應用程式啟動時,使用 @Value 註解的 Bean 會被範例化。所有使用了 @Value 註解的 Bean 會被加入到 PropertySourcesPlaceholderConfigurer 的後置處理器集合中。當後置處理器開始執行時,它會讀取 Bean 中所有 @Value 註解所標註的值,並通過反射將解析後的屬性值賦值給標有 @Value 註解的成員變數、方法引數和建構函式引數。重要!!! ⚠️注意 ①在使用 @Value 註解時需要確保注入的屬性值已經載入到 Spring 容器中,否則會導致注入失敗; ②建議參照變數的時候給定一個預設值,避免啟動報「缺失設定」的錯誤; ③通過依賴注入的方式獲取物件中屬性值,切記不要使用new的方式來建立物件獲取其屬性。 |
@ConfigurationProperties | SpringBoot 提供的一種更加便捷來處理組態檔中的屬性值的方式,可以通過自動繫結和型別轉換等機制,將指定字首的屬性集合自動繫結到一個Bean物件上。 |
@PropertySources | @PropertySources 註解的實現原理相對簡單,應用程式啟動時掃描所有被該註解標註的類,獲取到註解中指定自定義組態檔的路徑,將指定路徑下的組態檔內容載入到 Environment 中,這樣可以通過 @Value 註解或 Environment.getProperty() 方法來獲取其中定義的屬性值了。預設只限讀取properties檔案內容,想載入yaml檔案內容,可以自定義factory介面卡,指定factory具體的使用 |
YamlPropertiesFactoryBean物件 | 只限讀取yaml檔案,通過 @Value 註解或 Environment.getProperty() 方法來配合著獲取其中定義的屬性值。 |
JAVA原生 | 通過java.util.Properties去載入組態檔中的屬性, |
注入Environment類呼叫其方法getProperty(屬性key)即可
@Slf4j
@SpringBootTest
public class EnvironmentTest {
@Resource
private Environment env;
@Test
public void var1Test() {
String var1 = env.getProperty("env.var1");
log.info("Environment獲取的設定內容:{}", var1);
}
}
只要在變數上加註解 @Value("${env.var1}")就可以了,@Value 註解會自動將組態檔中的env.var1屬性值注入到var1欄位中。
@Slf4j
@SpringBootTest
public class EnvVariablesTest {
@Value("${env.var1}")
private String var1;
@Test
public void var1Test(){
log.info("組態檔屬性: {}",var1);
}
}
在 application.yml 組態檔中新增設定項:
env:
var1: 變數值1
var2: 變數值2
建立一個 MyConf 類用於承載所有字首為env的設定屬性。
@Data
@Configuration
@ConfigurationProperties(prefix = "env")
public class MyConf {
private String var1;
private String var2;
}
在需要使用var1、var2屬性值的地方,將 MyConf 物件注入到依賴物件中即可。
@Slf4j
@SpringBootTest
public class ConfTest {
@Resource
private MyConf myConf;
@Test
public void myConfTest() {
log.info("@ConfigurationProperties註解獲取的設定內容:{}", JSON.toJSONString(myConf));
}
}
在 src/main/resources/ 目錄下建立自定義組態檔 important.properties,增加兩個屬性。
env.var1=變數值1
env.var2=變數值2
在需要使用自定義組態檔的類上新增 @PropertySources 註解,註解 value屬性中指定自定義組態檔的路徑,可以指定多個路徑,用逗號隔開。
@Data
@Configuration
@PropertySources({
@PropertySource(value = "classpath:important.properties", encoding = "utf-8"),
@PropertySource(value = "classpath:important.properties",encoding = "utf-8")
})
public class PropertySourcesConf {
@Value("${env.var1}")
private String var1;
@Value("${env.var2}")
private String var2;
}
@Configuration
public class MyYamlConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer yamlConfigurer() {
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("test.yml"));
configurer.setProperties(Objects.requireNonNull(yaml.getObject()));
return configurer;
}
}
可以通過 @Value 註解或 Environment.getProperty() 方法來獲取其中定義的屬性值。
@Slf4j
@SpringBootTest
public class YamlTest {
@Value("${env.var3}")
private String var3;
@Test
public void myYamlTest() {
log.info("Yaml獲取設定內容:{}", var3);
}
}
@Slf4j
@SpringBootTest
public class CustomTest {
@Test
public void customTest() {
Properties props = new Properties();
try {
InputStreamReader inputStreamReader = new InputStreamReader(
this.getClass().getClassLoader().getResourceAsStream("test.properties"),
StandardCharsets.UTF_8);
props.load(inputStreamReader);
} catch (IOException e1) {
System.out.println(e1);
}
log.info("Properties Name:" + props.getProperty("env.appName"));
}
}
作者:京東零售 馬宏偉
來源:京東雲開發者社群 轉載請註明來源