SpringBoot讀取配置文件的6種實(shí)現(xiàn)方式
SpringBoot讀取配置文件的6種方式
在SpringBoot中,可以使用以下6種方式讀取 yml、properties配置:
- 使用@Value注解:讀取springboot全局配置文件單個(gè)配置。
- 使用Environment接口:通過(guò)Environment接口動(dòng)態(tài)獲取配置。(將yml全部數(shù)據(jù)封裝到Environment對(duì)象)
- 使用@ConfigurationProperties注解:在配置類(lèi)上使用@ConfigurationProperties注解并指定加載配置項(xiàng)的前綴,就可以批量讀取配置注入自定義類(lèi)的成員變量中。(自定義類(lèi)需要提供setter方法)
- 使用PropertySource注解:加載properties文件配置,然后在字段上使用@Value獲取配置。
- 配置PropertySourcesPlaceholderConfigurer的Bean加載自定義yml文件,然后在字段上使用@Value獲取配置。
- Java原生方式獲取配置。(IO流)
1. 使用@Value注解讀取單個(gè)配置
(1)編寫(xiě)application.yml文件配置:
student: name: 張三 age: 20
(2)使用@Value讀取配置:
@SpringBootTest @Slf4j public class ValueTest { @Value("${student.name}") private String name; @Value("${student.age}") private Integer age; @Test public void test() { log.info("@Value 配置獲取 name:{},age:{}",name,age); } }
@Value注意事項(xiàng):
@Value
注解只能讀取單個(gè)配置進(jìn)行賦值,無(wú)法讀取整個(gè)配置文件批量賦值。當(dāng)使用@Value注解讀取配置時(shí),確保配置在yml中存在,否則啟動(dòng)程序時(shí)就會(huì)報(bào)錯(cuò)。
注解中屬性名引用方式如下:
@Value("${一級(jí)屬性名.二級(jí)屬性名...}")
當(dāng)使用 @Value
注解引用屬性時(shí),可以在屬性名稱(chēng)后面使用冒號(hào)(: default-value
)的形式添加默認(rèn)值。
這樣,如果在配置文件中找不到對(duì)應(yīng)的屬性,就會(huì)使用默認(rèn)值。如果在配置文件中找到了屬性,其值將會(huì)覆蓋默認(rèn)值。
//可以使用各種類(lèi)型的默認(rèn)值,包括字符串、數(shù)字、布爾值等 @Value("${student.name:aopmin}") private String name; @Value("${student.age:18}") private Integer age;
//表示一個(gè)空字符串作為默認(rèn)值 @Value("${student.name:}") private String name;
@Value
注解只能用于被Spring管理的Bean中使用,如使用@Component
、@Service
、@Controller
等注解修飾的類(lèi),或者使用Java配置編寫(xiě)的@Configuration
類(lèi)中。@Value
注解可以用于字段、構(gòu)造函數(shù)參數(shù)、方法參數(shù)和方法上。當(dāng)將它放在方法上時(shí),Spring容器初始化時(shí)會(huì)調(diào)用該方法,并將配置屬性的值作為方法的參數(shù)傳遞進(jìn)去。
/* @Value注解被用于構(gòu)造函數(shù)參數(shù)、setter方法和普通方法上。容器初始化時(shí),會(huì)將配置屬性的值作為參數(shù)傳遞到構(gòu)造函數(shù)、setter方法和普通方法中。 */ @Component public class MyBean { private String myProperty; @Autowired public MyBean(@Value("${my.property}") String myProperty) { this.myProperty = myProperty; } @Value("${another.property}") public void setAnotherProperty(String anotherProperty) { // do something with anotherProperty... } @Value("${yet.another.property}") public void processValue(String value) { // do something with value... } }
@Value
注解不能在 static
修飾的字段上使用。因?yàn)锧Value注解是通過(guò)訪(fǎng)問(wèn)Spring容器中的上下文來(lái)解析屬性值并注入到目標(biāo)字段中的。
由于static字段不屬于對(duì)象實(shí)例,無(wú)法通過(guò)實(shí)例訪(fǎng)問(wèn)容器,所以在靜態(tài)字段上使用@Value注解是無(wú)效的。
2. 使用@ConfigurationProperties注解批量綁定
(1)編寫(xiě)application.yml文件配置:
student: name: zhangsan age: 18
(2)使用@ConfigurationProperties批量綁定:
package cn.hk.pojo; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 參數(shù)配置類(lèi) (需要提供setter方法) */ //將這個(gè)類(lèi)與配置文件前綴為student的配置綁定,然后把yml、properties中關(guān)于student的配置信息注入到當(dāng)前類(lèi)的成員變量中 @Component @Data @ConfigurationProperties(prefix = "student") public class StudentProperties { private String name; }
(3)測(cè)試
@SpringBootTest public class ConfigurationPropertiesTest { @Autowired private StudentProperties studentProperties; @Test public void test() { System.out.println("讀取配置: name==="+studentProperties.getName()); } }
@ConfigurationProperties注意事項(xiàng):
- 確保添加了@EnableConfigurationProperties注解:為了使@ConfigurationProperties生效,需要在主配置類(lèi)上添加@EnableConfigurationProperties(value=xxxxProperties.class)注解,開(kāi)啟@ConfigurationProperties注解自動(dòng)裝配功能。
- 配置文件中的屬性名與類(lèi)字段名的映射規(guī)則:默認(rèn)情況下,@ConfigurationProperties會(huì)將配置文件中的屬性名與類(lèi)字段名進(jìn)行映射。例如,配置文件中的屬性student.name會(huì)自動(dòng)映射到類(lèi)字段name上。如果配置文件中的屬性名與類(lèi)字段名不一致,可以使用@Value注解或通過(guò)setter方法來(lái)指定映射關(guān)系。
- 類(lèi)必須是Spring管理的Bean:被@ConfigurationProperties注解標(biāo)記的類(lèi)必須是由Spring容器管理的Bean,因此需要確保該類(lèi)被@Component或其他相關(guān)注解標(biāo)記,以便Spring能夠掃描并創(chuàng)建該類(lèi)的實(shí)例。
- 支持類(lèi)型轉(zhuǎn)換:@ConfigurationProperties支持自動(dòng)類(lèi)型轉(zhuǎn)換,將配置文件中的字符串值轉(zhuǎn)換為目標(biāo)字段的類(lèi)型。例如,將字符串轉(zhuǎn)換為整數(shù)、布爾值等。如果無(wú)法進(jìn)行類(lèi)型轉(zhuǎn)換,會(huì)拋出異常。
- 默認(rèn)值和可選屬性:可以為@ConfigurationProperties注解的字段設(shè)置默認(rèn)值,以防止配置文件中缺少對(duì)應(yīng)的屬性。可以使用":“符號(hào)指定默認(rèn)值,例如@Value(”${my.property:default-value}")。另外,可以使用required屬性來(lái)指定某個(gè)屬性是否為必需的。
- 配置項(xiàng)的驗(yàn)證和校驗(yàn):可以使用JSR-303/349規(guī)范的注解對(duì)@ConfigurationProperties注解的字段進(jìn)行驗(yàn)證和校驗(yàn)。例如,使用@NotBlank、@Min、@Max等注解來(lái)限制屬性值的有效性。
3. 使用Environment動(dòng)態(tài)獲取配置
(1)編寫(xiě)application.yml文件配置:
student: name: zhangsan age: 18
(2)使用Environment動(dòng)態(tài)獲取配置:(將Environment對(duì)象自動(dòng)裝配,然后調(diào)用getProperty()方法獲取指定屬性值)
package cn.hk.test; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.env.Environment; import javax.annotation.Resource; /** * Environment是springboot核心的環(huán)境配置接口,它提供了一些方法用于訪(fǎng)問(wèn)應(yīng)用程序配置屬性。 * 包括系統(tǒng)屬性、操作系統(tǒng)環(huán)境變量、命令行參數(shù)、以及配置文件中定義的屬性等等 */ @Slf4j @SpringBootTest public class EnvironmentTest { @Resource private Environment env; @Test public void test() { String name = env.getProperty("student.name"); // 邏輯處理...(也可以控制某一個(gè)bean是否生效) log.info("Environment配置讀取: name:{}", name); } }
除了自動(dòng)裝配方式,也可以從spring容器中獲取bean:
@Slf4j @SpringBootTest public class EnvironmentTest2 implements EnvironmentAware { private Environment env; @Test public void test() { String name = env.getProperty("student.name"); log.info("Environment配置讀取: name:{}", name); } @Override public void setEnvironment(Environment environment) { // 邏輯處理...(也可以控制某一個(gè)bean是否生效) this.env = environment; } }
Aware是Spring框架提供的一組特殊接口,可以讓Bean從Spring容器中拿到一些資源信息。
Aware接口是一種回調(diào)機(jī)制,當(dāng)Bean被實(shí)例化并注冊(cè)到Spring容器中時(shí),容器會(huì)自動(dòng)調(diào)用Bean中實(shí)現(xiàn)了特定Aware接口的方法,將相應(yīng)的資源或信息傳遞給Bean。
以下是幾個(gè)常用的Aware接口:
- ApplicationContextAware:通過(guò)實(shí)現(xiàn)該接口,Bean可以訪(fǎng)問(wèn)ApplicationContext對(duì)象,從而獲取Spring容器的相關(guān)信息。
- BeanFactoryAware:通過(guò)實(shí)現(xiàn)該接口,Bean可以訪(fǎng)問(wèn)BeanFactory對(duì)象,從而獲取Bean在容器中的相關(guān)信息。
- EnvironmentAware:通過(guò)實(shí)現(xiàn)該接口,Bean可以訪(fǎng)問(wèn)Environment對(duì)象,從而獲取環(huán)境相關(guān)的配置屬性,比如系統(tǒng)屬性、環(huán)境變量等。
- ResourceLoaderAware:通過(guò)實(shí)現(xiàn)該接口,Bean可以訪(fǎng)問(wèn)ResourceLoader對(duì)象,從而獲取資源加載器,用于加載類(lèi)路徑下的資源文件。
- MessageSourceAware:通過(guò)實(shí)現(xiàn)該接口,Bean可以訪(fǎng)問(wèn)MessageSource對(duì)象,從而獲取國(guó)際化消息。
4.使用@PropertySources注解獲取外部配置
前3種都是從springboot全局配置文件中獲取配置,如果獲取外部自定義文件就不可以啦,我們可以通過(guò)@PropertySources注解獲取==.properties==文件配置。
1、在resources目錄下創(chuàng)建student.properties文件:
student.id=1001 student.name=hello
2、在配置類(lèi)中使用@PropertySources注解綁定配置:
package cn.hk.pojo; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; /** * 綁定自定義properties配置 */ @Data @Configuration @PropertySource(value = "classpath:student.properties", encoding = "UTF-8") public class PropertySourcesConf { @Value("${student.id}") private Integer id; @Value("${student.name}") private String name; }
3、測(cè)試
@SpringBootTest @Slf4j public class PropertySourcesTest { @Resource private PropertySourcesConf propertySourcesConf; @Test public void test() { log.info("PropertySources配置讀取 id: {}", propertySourcesConf.getId()); log.info("name: {}", propertySourcesConf.getName()); } }
5. 配置PropertySourcesPlaceholderConfigurer的Bean獲取外部配置
1、編寫(xiě)student.yml配置:
file: type: text
2、 配置PropertySourcesPlaceholderConfigurer獲取自定義yml文件配置:
package cn.hk.config; import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.io.ClassPathResource; import java.util.Objects; /** * 配置PropertySourcesPlaceholderConfigurer讀取yml配置 */ @Configuration public class MyYamlConfig { @Bean public static PropertySourcesPlaceholderConfigurer yamlConfigurer() { PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer(); YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean(); yaml.setResources(new ClassPathResource("student.yml"));//自定義yml文件 //Objects.requireNonNull()方法的作用是如果對(duì)象為空,則拋出空指針異常,否則返回對(duì)象本身。 configurer.setProperties(Objects.requireNonNull(yaml.getObject())); return configurer; } }
3、測(cè)試
@SpringBootTest public class LoadYamlTest { @Value("${file.type}") private String fileType; @Test public void test() { System.out.println("讀取yaml配置:"+fileType); } }
6. Java原生方式獲取配置
通過(guò)IO流讀取配置,然后放入propertis配置對(duì)象中。
package cn.hk.test; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.Properties; @SpringBootTest public class CustomTest { @Test public void test() { // 配置對(duì)象 Properties props = new Properties(); InputStreamReader input = null; try { // 輸入流 (字節(jié)流轉(zhuǎn)字符流) input = new InputStreamReader( //通過(guò)類(lèi)加載器來(lái)獲取指定路徑下的資源文件,并返回一個(gè)InputStream對(duì)象 this.getClass().getClassLoader().getResourceAsStream("student.properties"), StandardCharsets.UTF_8); //指定編碼格式 // 加載配置 props.load(input); } catch (IOException e) { throw new RuntimeException(e); } finally { if (input!=null) try { input.close(); } catch (IOException e) { e.printStackTrace(); } } // 獲取配置 System.out.println("id:" + props.getProperty("student.id") + ", name:" + props.getProperty("student.name")); } }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- springboot打包無(wú)法讀取yml、properties等配置文件的解決
- springboot讀取.properties配置文件中的map和list類(lèi)型配置參數(shù)方式
- SpringBoot讀取外部的配置文件的代碼實(shí)現(xiàn)
- springboot配置文件如何實(shí)現(xiàn)多個(gè)yml相互讀取問(wèn)題
- Springboot注解@Value讀取配置文件參數(shù)詳解
- SpringBoot3讀取配置文件application.properties屬性值的幾種方式
- SpringBoot配置文件、多環(huán)境配置、讀取配置的4種實(shí)現(xiàn)方式
相關(guān)文章
java編程中拷貝數(shù)組的方式及相關(guān)問(wèn)題分析
這篇文章主要介紹了java編程中拷貝數(shù)組的方式及相關(guān)問(wèn)題分析,分享了Java中數(shù)組復(fù)制的四種方式,其次對(duì)二維數(shù)組的簡(jiǎn)單使用有一段代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11【Java IO流】字節(jié)流和字符流的實(shí)例講解
下面小編就為大家?guī)?lái)一篇【Java IO流】字節(jié)流和字符流的實(shí)例講解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09Spring 面向切面編程AOP實(shí)現(xiàn)詳解
這篇文章主要介紹了Spring 面向切面編程AOP實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09多模塊項(xiàng)目使用枚舉配置spring-cache緩存方案詳解
這篇文章主要為大家介紹了多模塊項(xiàng)目使用枚舉配置spring-cache緩存的方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05使用java springboot設(shè)計(jì)實(shí)現(xiàn)的圖書(shū)管理系統(tǒng)(建議收藏)
這篇文章主要介紹了使用java springboot設(shè)計(jì)實(shí)現(xiàn)的圖書(shū)管理系統(tǒng),包含了整個(gè)的開(kāi)發(fā)過(guò)程,以及過(guò)程中遇到的問(wèn)題和解決方法,對(duì)大家的學(xué)習(xí)和工作具有借鑒意義,建議收藏一下2021-08-08使用java代碼代替xml實(shí)現(xiàn)SSM教程
這篇文章主要介紹了使用java代碼代替xml實(shí)現(xiàn)SSM教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12java實(shí)現(xiàn)百度坐標(biāo)的摩卡托坐標(biāo)與火星坐標(biāo)轉(zhuǎn)換的示例
這篇文章主要介紹了java實(shí)現(xiàn)百度坐標(biāo)的摩卡托坐標(biāo)與火星坐標(biāo)轉(zhuǎn)換的示例,需要的朋友可以參考下2014-03-03grade構(gòu)建閱讀spring源碼環(huán)境 Idea2020.3的過(guò)程
這篇文章主要介紹了grade構(gòu)建閱讀spring源碼環(huán)境 Idea2020.3,本文分步驟通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10