浅析SpringBoot加载配置的6种方式 | 京东云技术团队

京东云开发者
• 阅读 251

从配置文件中获取属性应该是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

注入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 注解

只要在变量上加注解 @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);
    }
}

三、@ConfigurationProperties 注解

在 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));
    }
}

四、@PropertySources 注解

在 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;
}

五、YamlPropertiesFactoryBean 加载 YAML 文件

@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);
    }
}

六、JAVA原生读取

@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"));
    }
}

作者:京东零售 马宏伟

来源:京东云开发者社区 转载请注明来源

点赞
收藏
评论区
推荐文章
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Peter20 Peter20
3年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Stella981 Stella981
3年前
BeetlSQL 3.0.10 发布,多数据源分布式sega事务支持
本次发布主要增加了分布式Sega事务支持,适合多数据源按照社区建议,修改了了springboot的yml配置方式修改了@Jackson和@UpdateTime,本来是用来作为例子,但社区开发者提供了较好的完整实现增加Sega支持<dependency<groupIdcom.ibeetl</gr
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Stella981 Stella981
3年前
SpringBoot开发案例之整合Dubbo提供者(二)
!00.jpg(https://blog.52itstyle.com/usr/uploads/2017/07/1329278006.jpg)大家有没有注意到,上一篇中提供者,暴露接口的方式?混搭。springboot本身接口实现使用了注解的方式,而Dubbo暴露接口使用的是配置文件的实现方式,即如下:代码importorg.s
Easter79 Easter79
3年前
SpringBoot开发案例之整合Dubbo提供者(二)
!00.jpg(https://blog.52itstyle.com/usr/uploads/2017/07/1329278006.jpg)大家有没有注意到,上一篇中提供者,暴露接口的方式?混搭。springboot本身接口实现使用了注解的方式,而Dubbo暴露接口使用的是配置文件的实现方式,即如下:代码importorg.s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这