SpringBoot读取配置文件中的内容

文章目录

  • 1. 读取配置文件application.yml中内容的方法
    • 1.1 Environment
    • 1.2 @Value注解
    • 1.3 @ConfigurationProperties 注解
    • 1.4 @PropertySources 注解,获取自定义配置文件中的内容,yml文件需要自行实现适配器
    • 1.5 YamlPropertiesFactoryBean 加载 YAML 文件
    • 1.6 各种方式总结
  • 2. 自定义的配置文件,如果不使用配置类加载,即使放在resources目录下也是获取不到内容的
  • 3. 如果两个文件的key重复了,以默认配置文件application.yml中的内容为准

配置文件application.yml:

server:
  port: 8001
blog:
  user: 
    name: xinliushijian
    home: 徐州
    work: 上海
    marathonpb: 419

1. 读取配置文件application.yml中内容的方法

1.1 Environment

  • Environment 是 springboot 核心的环境配置接口,它提供了简单的方法来访问应用程序属性,包括系统属性、操作系统环境变量、命令行参数、和应用程序配置文件中定义的属性等等。

  • Springboot 程序启动加载流程里,会执行SpringApplication.run中的prepareEnvironment()方法进行配置的初始化

  • 使用 Environment 方式来获取配置属性值非常简单,只要注入Environment类调用其方法getProperty(属性key)即可

示例代码:

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

import static org.junit.jupiter.api.Assertions.assertEquals;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = XinJavaDemoApplication.class)
@Slf4j
public class EnvironmentTest {

    @Resource
    private Environment env;

    @Test
    public void test1() {
        String port = env.getProperty("server.port");
        System.out.println("port: " + port);
        assertEquals(port, "8001");
    }

    @Test
    public void test2() {
        String home = env.getProperty("blog.user.home");
        System.out.println("blog.user.home: " + home);
        assertEquals(home, "徐州");
    }
    
}

key不存在时,执行不会报错,value为null

在这里插入图片描述

1.2 @Value注解

  • @Value注解是Spring框架提供的用于注入配置属性值的注解,它可用于类的成员变量、方法参数和构造函数参数上,这个记住很重要!

  • 在应用程序启动时,使用 @Value 注解的 Bean 会被实例化。所有使用了 @Value 注解的 Bean 会被加入到 PropertySourcesPlaceholderConfigurer 的后置处理器集合中。

  • 当后置处理器开始执行时,它会读取 Bean 中所有 @Value 注解所标注的值,并通过反射将解析后的属性值赋值给标有 @Value 注解的成员变量、方法参数和构造函数参数。

  • 需要注意,在使用 @Value 注解时需要确保注入的属性值已经加载到 Spring 容器中,否则会导致注入失败。

  • 只有标注了@Component、@Service、@Controller、@Repository 或 @Configuration 等容器管理注解的类,由 Spring 管理的 bean 中使用 @Value注解才会生效。而对于普通的POJO类,则无法使用 @Value注解进行属性注入。

  • 如果我们想要获取 TestService 类中的某个变量的属性值,需要使用依赖注入的方式,而不能使用 new 的方式。通过依赖注入的方式创建 TestService 对象,Spring 会在创建对象时将对象所需的属性值注入到其中。

key不存在时,执行会报错:

在这里插入图片描述

key不存在时,给出默认值,执行不会报错,结果就是取默认值:

在这里插入图片描述

示例代码:

    @Value("${blog.user.homeeeee:徐州}")
    private String home;

    @Test
    public void testValue() {

        System.out.println("home: " + home);
        assertEquals("徐州", home);
    }

正常取值:

在这里插入图片描述

1.3 @ConfigurationProperties 注解

@ConfigurationProperties注解是 SpringBoot 提供的一种更加便捷来处理配置文件中的属性值的方式,可以通过自动绑定和类型转换等机制,将指定前缀的属性集合自动绑定到一个Bean对象上

加载原理:

  • 在 Springboot 启动流程加载配置的 prepareEnvironment() 方法中,有一个重要的步骤方法 bindToSpringApplication(environment),它的作用是将配置文件中的属性值绑定到被 @ConfigurationProperties 注解标记的 Bean对象中。但此时这些对象还没有被 Spring 容器管理,因此无法完成属性的自动注入。

  • 那么这些Bean对象又是什么时候被注册到 Spring 容器中的呢?

  • 这就涉及到了 ConfigurationPropertiesBindingPostProcessor 类,它是 Bean后置处理器,负责扫描容器中所有被 @ConfigurationProperties 注解所标记的 Bean对象。如果找到了,则会使用 Binder 组件将外部属性的值绑定到它们身上,从而实现自动注入。

创建配置类,prefix + 属性名 = 配置key

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "blog.user")
public class BlogUser {
    private String name;

    private String home;

    private String work;

    private String marathon;

    private String nameeeee;
}

示例代码:

    @Resource
    private BlogUser blogUser;

    @Test
    public void testConfig() {

        System.out.println("blogUser: " + JSONObject.toJSONString(blogUser));
        System.out.println("nameeeee: " + blogUser.getNameeeee());
    }

属性名在配置文件中不存在时,获取此属性值的时候,执行不会报错,结果为null

在这里插入图片描述

1.4 @PropertySources 注解,获取自定义配置文件中的内容,yml文件需要自行实现适配器

  • 除了系统默认的 application.yml 或者 application.properties 文件外,我们还可能需要使用自定义的配置文件来实现更加灵活和个性化的配置。与默认的配置文件不同的是,自定义的配置文件无法被应用自动加载,需要我们手动指定加载。

  • @PropertySources 注解的实现原理相对简单,应用程序启动时扫描所有被该注解标注的类,获取到注解中指定自定义配置文件的路径,将指定路径下的配置文件内容加载到 Environment 中,这样可以通过 @Value 注解或 Environment.getProperty() 方法来获取其中定义的属性值了。

  • 当加载.yaml文件时,启动项目居然报错了,经过一番摸索我发现,@PropertySources 注解只内置了PropertySourceFactory适配器。也就是说它只能加载.properties文件。

  • 如果想要加载一个.yaml类型文件,则需要自行实现yaml的适配器 YamlPropertySourceFactory

  • 而在加载配置时要显示的指定使用 YamlPropertySourceFactory适配器,这样就完成了@PropertySource注解加载 yaml 文件。

支持.properties文件,若是.yml文件则自行实现yaml的适配器,否则识别不了,@Value注解中没给默认值启动时就会报错

增加自定义配置文件

xinliushijian.properties:

blog.user.name=心流时间
blog.user.home=徐州
blog.user.work=上海
blog.user.marathon: 419

xinliu.yml:

new:
  year: 2024
  month: 01
  day: 04

其中用到的@Value注解,在key不存在时报错(启动时)

在这里插入图片描述

在@Value注解中加上默认值,执行就不报错了

在这里插入图片描述

不通过bean,通过new 构造器的方法得到对象获得属性值,执行不报错,结果为null

在这里插入图片描述

xinliu.yml文件中的内容识别不到,启动时就会报错,需要自行实现yaml的适配器

在这里插入图片描述

配置类示例代码

import lombok.Data;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.beans.factory.annotation.Value;

@Data
@Configuration
@PropertySources({
        @PropertySource(value = "classpath:xinliushijian.properties",encoding = "utf-8"),
        @PropertySource(value = "classpath:xinliu.yml",encoding = "utf-8",factory = YamlPropertySourceFactory.class)
})
public class PropertySourcesConf {

    @Value("${blog.user.home:xuzhou}")
    private String home;

    @Value("${blog.user.nameeee:xinliushijian}")
    private String name;

    @Value("${new.year:2023}")
    private String year;
    
}

yaml适配器示例代码:

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;

import java.io.IOException;
import java.util.Properties;

public class YamlPropertySourceFactory implements PropertySourceFactory {

    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(encodedResource.getResource());

        Properties properties = factory.getObject();

        return new PropertiesPropertySource(encodedResource.getResource().getFilename(), properties);
    }
}

测试类示例代码:

	@Autowired
    private PropertySourcesConf propertySourcesConf;

    @Test
    public void testProp() {
        System.out.println("propertySourcesConf: " + JSONObject.toJSONString(propertySourcesConf));
        System.out.println("nameeeee: " + propertySourcesConf.getName());
        System.out.println("year: " + propertySourcesConf.getYear());
    }

1.5 YamlPropertiesFactoryBean 加载 YAML 文件

我们可以使用 YamlPropertiesFactoryBean 类将 YAML 配置文件中的属性值注入到 Bean 中。

配置类

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;

@Configuration
public class MyYamlConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer yamlConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
        yaml.setResources(new ClassPathResource("xinliu.yml"));
        configurer.setProperties(Objects.requireNonNull(yaml.getObject()));
        return configurer;
    }
}

可以通过 @Value 注解或 Environment.getProperty() 方法来获取其中定义的属性值。

在这里插入图片描述

1.6 各种方式总结

  • 我们可以通过 @Value 注解、Environment 类、@ConfigurationProperties 注解、@PropertySource 注解等方式来获取配置信息。

  • 其中,@Value 注解适用于单个值的注入,而其他几种方式适用于批量配置的注入。不同的方式在效率、灵活性、易用性等方面存在差异,在选择配置获取方式时,还需要考虑个人编程习惯和业务需求。

  • 如果重视代码的可读性和可维护性,则可以选择使用 @ConfigurationProperties 注解;如果更注重运行效率,则可以选择使用 Environment 类。总之,不同的场景需要选择不同的方式,以达到最优的效果。

2. 自定义的配置文件,如果不使用配置类加载,即使放在resources目录下也是获取不到内容的

自定义文件:xinliushijianhaha.yml

newnew:
  year: 2024
  month: 01
  day: 04

测试结果:
在这里插入图片描述

3. 如果两个文件的key重复了,以默认配置文件application.yml中的内容为准

application.yml中的配置:

在这里插入图片描述

自定义配置文件(有用配置类自动加载)xinliu.yml:

在这里插入图片描述

测试结果:

在这里插入图片描述

结果分析:

  • application.yml这种默认的配置文件中的key和自定义配置文件中的key相等时,以application.yml中的内容为准
  • 当配置内容是数字时,前面的0会消失(value是04,得到的结果是4,自动减去了0)

引用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/318441.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【计算机组成原理】高速缓冲存储器 Cache 的常用替换算法(Replacement Algorithm)

替换算法 Replacement Algorithm 缓存替换算法用于确定在缓存满时需要替换哪些缓存块以便为新的数据腾出空间。 先进先出 First-In-First-Out FIFO算法将最早进入缓存的块替换出去。这种算法实现较为简单&#xff0c;但可能导致早被访问的数据被频繁替换&#xff0c;而近期使…

01循环算法

1.求小数点的某一位&#xff0c;且超出float和double的精度问题 【题目描述】 分数a/b化为小数后&#xff0c;小数点后第n位的数字是多少&#xff1f; 【输入】 三个正整数a&#xff0c;b&#xff0c;n&#xff0c;相邻两个数之间用单个空格隔开。0<a<b<100&#…

Leetcode with Golang 滑动窗口 Part1

滑动窗口的定义&#xff1a; 滑动窗口这一个技巧主要运用于处理数组问题上&#xff0c;一般用于“子串”问题。精髓是&#xff0c;维护一个里面装着元素的“窗口”&#xff0c;在将新元素装进“窗口”的同时&#xff0c;根据题意&#xff0c;把不符合题意的元素踢出“窗口”。…

远程开发之vacode插件Remote - SSH

远程开发之vacode插件Remote - SSH vscode插件(Remote - SSH)ssh config自定义配置跳板机ssh-agent配置(使ForwardAgent配置生效, 免密拉代码)拷贝公钥到服务器(实现免密登录服务器) 通过vscode的Remote - SSH插件, 实现远程服务器进行像本地操作一样使用远程服务器, 亦可进行像…

第 3 场 小白入门赛(1~6) + 第 3 场 强者挑战赛 (1 ~ 5)

第 3 场 小白入门赛 1、厉不厉害你坤哥&#xff08;暴力&#xff09; 2、思维 3、暴力&#xff0c;前缀和&#xff0c;贪心 4、二分 5、DP 6、容斥&#xff0c;双指针 第 3 场 强者挑战赛 2、BFS 5、树上倍增求第k祖先 1. 召唤神坤 题意&#xff1a; 可以发现,如果我…

Python Flask教程

Flask Doc: https://rest-apis-flask.teclado.com/docs/course_intro/what_is_rest_api/Github: https://github.com/tecladocode/rest-apis-flask-python 1. 最简单的应用 最小应用 from flask import Flaskapp Flask(__name__)app.route("/") def hello_world()…

“华为杯“第四届中国研究生数学建模竞赛-D题:邮路规划与邮车调度

目录 摘 要&#xff1a; 1.问题的重述 2.模型的假设与符号说明 2.1 针对本问题&#xff0c;本文做出如下假设 2.2 符号说明 3.问题的数学模型 4.问题的求解 4.1 问题一的求解 4.1.1 最少邮车数的求法 4.1.2 邮路规划及路径选择 4.1.3 问题的求解结果 4.2 问题二的求…

记录下载安装rabbitmq(Linux) 并整合springboot--详细版(全)

下载rabbitmq&#xff08;Linux&#xff09;&#xff1a; erlang压缩包&#xff1a; https://share.weiyun.com/TGhfV8eZ rabbitMq-server压缩包&#xff1a; https://share.weiyun.com/ZXbUwWHD &#xff08;因为RabbitMQ采用 Erlang 实现的工业级的消息队列(MQ)服务器&#…

推荐一款.NET开发的物联网开源项目

物联网&#xff08;IoT&#xff09;是一个正在快速发展的技术领域&#xff0c;它涉及到各种设备、物体和系统的互联。所以各种物联网平台和物联网网关项目层出不穷&#xff0c;在物联网&#xff08;IoT&#xff09;领域&#xff0c;.NET平台扮演着重要的角色。作为一款广泛使用…

备战抖音商城好物年货节,品牌焕发新商机

农历春节前的最后一个月&#xff0c;打工人们逐渐将置办年货提上日程。忙碌了一年的辛苦与疲惫&#xff0c;总能在喜气洋洋买年货的过程中&#xff0c;被一扫而空。这是“年味”的开始&#xff0c;也是公司高管郭广宇面临的一场关键战役。 郭广宇今年35岁&#xff0c;是三只松鼠…

强化学习应用(八):基于Q-learning的无人机物流路径规划研究(提供Python代码)

一、Q-learning简介 Q-learning是一种强化学习算法&#xff0c;用于解决基于马尔可夫决策过程&#xff08;MDP&#xff09;的问题。它通过学习一个价值函数来指导智能体在环境中做出决策&#xff0c;以最大化累积奖励。 Q-learning算法的核心思想是通过不断更新一个称为Q值的…

uni-app做A-Z排序通讯录、索引列表

上图是效果图&#xff0c;三个问题 访问电话通讯录&#xff0c;拿数据拿到用户的联系人数组对象&#xff0c;之后根据A-Z排序根据字母索引快速搜索 首先说数据怎么拿 - 社区有指导https://ask.dcloud.net.cn/question/64117 uniapp 调取通讯录 // #ifdef APP-PLUSplus.contac…

【深度学习目标检测】十六、基于深度学习的麦穗头系统-含GUI和源码(python,yolov8)

全球麦穗检测是植物表型分析领域的一个挑战&#xff0c;主要目标是检测图像中的小麦麦穗。这种检测在农业领域具有重要意义&#xff0c;可以帮助农民评估作物的健康状况和成熟度。然而&#xff0c;由于小麦麦穗在视觉上具有挑战性&#xff0c;准确检测它们是一项艰巨的任务。 全…

DP读书:《openEuler操作系统》(八)TCP、UDP与跨机器通讯

10min速通TCP与UDP 2024 DP读书计算机网络简介TCP/IP协议栈A. 物理层1.信号及信道传递2.信号调制与调解3.信道的复用 B. 数据链路层1.封装成帧2.透明传输3.差错控制 C. 网络层1.IP2.ARP3.路由选择协议 D. 传输层1.端口号2.3.UDP 2024 DP读书 第八章 跨机器通讯 在第六章之中&a…

翻译: Streamlit从入门到精通 基础控件 一

这个关于Streamlit的教程旨在帮助数据科学家或机器学习工程师&#xff0c;他们不是网络开发者&#xff0c;也不想花费数周时间学习使用这些框架来构建网络应用程序。 1. 什么是Streamlit&#xff1f; Streamlit是一个免费且开源的框架&#xff0c;用于快速构建和共享美观的机器…

(南京观海微电子)——色温介绍

色温是表示光线中包含颜色成分的一个计量单位。从理论上说&#xff0c;黑体温度指绝对黑体从绝对零度&#xff08;&#xff0d;273℃&#xff09;开始加温后所呈现的颜色。黑体在受热后&#xff0c;逐渐由黑变红&#xff0c;转黄&#xff0c;发白&#xff0c;最后发出蓝色光。当…

【MCAL】MCU模块详解

目录 前言 正文 1. MCU模块介绍 2. MCU依赖的模块 3. MCU模块提供服务 3.1 时钟的初始化 3.2 MCU模式的配置 3.3 MCU软件复位功能 3.4 RAM的初始化 4.MCU重要数据类型 4.1 Mcu_ResetType 4.2 Mcu_ModeType 5. MCU重要API 5.1 Mcu_Init 5.2 Mcu_InitClock 5.3 M…

qayrup-switch开发文档

因为只是一个小组件,所以直接拿csdn当开发文档了 书接上文uniapp怎么开发插件并发布 : https://blog.csdn.net/weixin_44368963/article/details/135576511 因为我业没有开发过uniapp的组件,所以我看到下面这个文件还是有点懵的 也不清楚怎么引入, 然后去翻了翻官方文档,官方…

Java设计模式-备忘录模式

备忘录模式 一、概述二、结构三、案例实现&#xff08;一&#xff09;“白箱”备忘录模式&#xff08;二&#xff09;“黑箱”备忘录模式 四、优缺点五、使用场景 一、概述 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以方便地回到一个特定的历史步骤&…

系列七、Spring Security中基于Jdbc的用户认证 授权

一、Spring Security中基于Jdbc的用户认证 & 授权 1.1、概述 前面的系列文章介绍了基于内存定义用户的方式&#xff0c;其实Spring Security中还提供了基于Jdbc的用户认证 & 授权&#xff0c;再说基于Jdbc的用户认证 & 授权之前&#xff0c;不得不说一下Spring Se…