前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot中读取配置的几种方式

SpringBoot中读取配置的几种方式

作者头像
半月无霜
发布2023-03-03 14:54:43
5020
发布2023-03-03 14:54:43
举报
文章被收录于专栏:半月无霜半月无霜

SpringBoot中读取配置的几种方式

一、介绍

在SpringBoot项目中,我们使用application.yml或者application.properties文件,那么在如何读取其中的配置参数呢?

有以下这么几种

  1. 使用@Value注解
  2. 使用@ConfigurationProperties注解
  3. 使用@PropertySource+@Value注解
  4. 使用@PropertySource+@ConfigurationProperties注解
  5. 使用Environment.getProperty()

前面两种大家都很熟悉,也在常常使用,剩下这几个就比较陌生了,一起来看看吧。

二、方法

1)@Value注解

假如我们有这样的一个application.yml配置文件

代码语言:javascript
复制
server:
  port: 8888

对于这样单条的配置,我们可以采用@Value去进行获取

代码语言:javascript
复制
package com.banmoon.test.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class TestJob {

    @Value("${server.port}")
    private Integer port;

    @Scheduled(cron = "0/3 * * * * *")
    public void start(){
        log.info("端口号:{}", port);
    }

}
image-20220408193720017
image-20220408193720017

优缺点也很明显,简单快捷,但只能单个单个获取,如果要获取一批配置就会显得十分繁琐


注意,@Value不能用来修饰静态属性,会读取不到,导致属性为Null的

修改一下上面的属性,让它变成静态属性

代码语言:javascript
复制
package com.banmoon.test.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class TestJob {

    @Value("${server.port}")
    private static Integer port;

    @Scheduled(cron = "0/3 * * * * *")
    public void start(){
        log.info("端口号:{}", port);
    }

}
image-20220408194155386
image-20220408194155386

那么,如果非要使用静态属性该怎么办呢?虽然不建议使用,哎可以改成这样。

代码语言:javascript
复制
package com.banmoon.test.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class TestJob {

    private static Integer port;

    @Value("${server.port}")
    public void setPort(Integer port) {
        TestJob.port = port;
    }

    @Scheduled(cron = "0/3 * * * * *")
    public void start(){
        log.info("端口号:{}", port);
    }

}

聪明的你马上就知道了是怎么一回事了,这和Bean的初始化有关。如果不懂,还是不要使用了,不然说不定获取到的还是一个Null

image-20220408194533045
image-20220408194533045

2)@ConfigurationProperties注解

这个注解也十分熟悉,它可以将配置信息映射成我们的一个Bean,通过这个Bean,我们就可以获取到配置的信息啦。它解决上面@Value只能一个一个去获取配置的繁琐痛点。

假设我们现在有这样的一个配置

代码语言:javascript
复制
user:
  name: banmoon
  age: 18
  sex: 男
  friends:
    - 阿超
    - 九月

那么,我们只需要这样做,就可以映射成我们这个Bean了

代码语言:javascript
复制
package com.banmoon.test.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;

@Data
@Component
@ConfigurationProperties(prefix = "user")
public class UserProperties implements Serializable {

    private String name;

    private Integer age;

    private String sex;

    private List<String> friends;

}

我们再获取一下这个Bean,打印一下里面的信息

代码语言:javascript
复制
package com.banmoon.test.job;

import com.banmoon.test.config.UserProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Slf4j
@Component
public class TestJob {

    @Autowired
    private UserProperties userProperties;

    @PostConstruct
    public void start(){
        log.info("user配置信息:{}", userProperties);
    }

}
image-20220408195819605
image-20220408195819605

这个注解比起@Value,编码的效率就快了不少

3)@PropertySource+@Value注解

在开发中,我们不只有application.yml一个配置文件,我们可能有多个,如果要加载其他的配置文件时。

@PropertySource注解就派上用场了,指定了加载哪个配置文件作为配置源。

假设我们现在多了一个user.properties的配置文件

代码语言:javascript
复制
other.port=2333

只需要小改,在类上添加@PropertySource注解,指定加载这个配置文件即可。

由于@PropertySource只是指定了加载哪个配置文件,所以它还需要搭配@Value注解进行使用

代码语言:javascript
复制
package com.banmoon.test.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@PropertySource("classpath:user.properties")
public class TestJob {

    @Value("${other.port}")
    private String port;

    @Scheduled(cron = "0/3 * * * * *")
    public void start(){
        log.info("其他端口:{}", port);
    }

}
image-20220408222910402
image-20220408222910402

4)@PropertySource+@ConfigurationProperties注解

既然@PropertySource注解是指定加载某个配置文件,需要搭配@Value使用,那么它也可以搭配@ConfigurationProperties注解进行使用。

同样在user.properties文件中

代码语言:javascript
复制
user.name=banmoon
user.age=18
user.sex=男
user.friends[0]=钟离
user.friends[1]=巴尔

我们只需要在类上指定上@PropertySource即可

代码语言:javascript
复制
package com.banmoon.test.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;

@Data
@Component
@PropertySource("classpath:user.properties")
@ConfigurationProperties(prefix = "user")
public class UserProperties implements Serializable {

    private String name;

    private Integer age;

    private String sex;

    private List<String> friends;

}

在使用上,同上,这里代码就不贴出来了

image-20220408231145746
image-20220408231145746

5)Environment.getProperty()

最后一种,见都没有见过,环境获取参数?

同样测试一下,获取个端口看看

代码语言:javascript
复制
package com.banmoon.test.job;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class TestJob {

    @Autowired
    private Environment environment;

    @Scheduled(cron = "0/3 * * * * *")
    public void start(){
        log.info("【environment】当前端口:{}", environment.getProperty("server.port"));
    }

}
image-20220408234442334
image-20220408234442334

此方法,支持动态的获取需要的参数,虽然平常不常用,但还是做一下记录。

三、@PropertySource加载yml文件

在上面的示例中,@PropertySource加载的是properties文件,不代表它只能加载properties文件

比如说这次我们添加一个example.yml文件

代码语言:javascript
复制
example:
	name: 半月无霜

在加载时,我们只需要这样指定就行

代码语言:javascript
复制
package com.banmoon.test.job;

import com.banmoon.test.config.YamlPropertySourceFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@PropertySource(value = "classpath:example.yml", factory = YamlPropertySourceFactory.class)
public class TestJob {

    @Value("${example.name}")
    private String name;

    @Scheduled(cron = "0/3 * * * * *")
    public void start(){
        log.info("加载其他yaml文件:{}", name);
    }

}
image-20220409093416702
image-20220409093416702

至于YamlPropertySourceFactory.java,这是我们自己实现的一个类,如下可以直接使用

代码语言:javascript
复制
package com.banmoon.test.config;

import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;

import java.io.IOException;
import java.util.List;

public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        if (resource == null)
            return super.createPropertySource(name, resource);
        List<PropertySource<?>> sources = new YamlPropertySourceLoader()
                .load(resource.getResource().getFilename(), resource.getResource());
        return sources.get(0);
    }

}

四、最后

我是半月,祝你幸福!!!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • SpringBoot中读取配置的几种方式
    • 一、介绍
      • 二、方法
        • 1)@Value注解
        • 2)@ConfigurationProperties注解
        • 3)@PropertySource+@Value注解
        • 4)@PropertySource+@ConfigurationProperties注解
        • 5)Environment.getProperty()
      • 三、@PropertySource加载yml文件
        • 四、最后
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档