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

第二章 SpringBoot环境下yml和properties的几种玩法

目录

一、yml和properties比较

 二、yml注入属性值到实体

2.1. 松散绑定语法

2.2. JSR303数据校验

三、properties注入属性值到实体

四、配置文件位置及多环境配置

4.1. 配置文件位置

​编辑4.2. 多环境配置

4.2.1. 方式1

 4.2.2. 方式2


一、yml和properties比较

本文主要讲解SpringBoot工程环境下,通过yml和properties两种配置文件形式,将JavaConfig绑定配置文件的值,以及关于yml文件的一些非常规的玩法。以下是yml和properties的主要对比:

JSR303数据校验‌是一种后端数据校验支持,它是Java Specification Requests (JSR) 303的一部分,属于Java EE 6的一项子规范,也被称为Bean Validation。这个规范为Bean验证定义了元数据模型和API,使得开发者能够为Java对象添加验证规则,确保数据的完整性和准确性。JSR303数据校验主要通过注解(Annotations)来实现,这些注解被添加到Java类的字段上,用于定义验证规则。例如,:ml-search[@NotNull]用于验证字段值不能为null,:ml-search[@NotEmpty]用于验证字符串字段不能为空,:ml-search[@Size]用于验证字符串、集合或数组字段的长度或大小等。此外,JSR303还支持更复杂的校验需求,如分组校验(针对不同场景的复杂校验)和自定义校验。

JSR303数据校验的重要性在于,它提供了一种在数据进入业务逻辑之前进行验证的方法,从而减少了因数据问题导致的错误和异常。通过结合前端校验和后端校验,可以进一步提高系统的健壮性和数据的安全性。在实际应用中,JSR303注解被广泛应用于Spring Boot等框架中,使得数据校验变得更加简单和高效‌。

除此以外,yml和properties文件格式的主要区别在于语法、数据类型、可读性、扩展性、语言通用性以及优先级。

  • 语法‌:YAML使用缩进和冒号来表示层次结构,而Properties使用等号和点号分隔键值对。YAML的语法更加简洁、易读,支持注释和多行文本,而Properties的语法相对简单,不支持注释和多行文本‌。

  • 数据类型‌:YAML支持多种数据类型,如字符串、数字、布尔值、数组、对象等,可以更好地表示复杂的数据结构。相比之下,Properties只支持字符串类型‌。

  • 可读性‌:YAML的语法使得配置信息更易于组织和描述复杂的配置,而Properties的语法不太适合描述复杂的配置信息‌。

  • 扩展性‌:YAML支持自定义标签和类型,可以扩展语言的功能和表达能力,而Properties的扩展性相对较低‌。

  • 语言通用性‌:Properties格式的配置文件只适用于Spring Boot项目,也就是只适用于Java语言。而YAML支持更多的开发语言,可以用在Java、PHP、Python、Ruby、JavaScript、Perl、Golang等语言中‌。

  • 优先级‌:在SpringBoot中,如果同时存在YAML和Properties配置文件,YAML文件的优先级高于Properties文件‌。

 二、yml注入属性值到实体

package com.example.pojo;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.List;
import java.util.Map;/*** @ConfigurationProperties作用:* 将配置文件中配置的每个属性的值,映射到这个组件中* 告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定* 参数prefix = "person":将配置文件中的person下面的所有属性一一对应* 只有这个组件是容器中的组件,才能使用容器提供的ConfigurationProperties功能* 因此需要通过注解@Component来注册Bean*/
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class Person {private String name;private int age;private boolean isWork;private Date birth;private Map<String, Object> maps;private List<Object> list;private Pet pet;
}
package com.example.pojo;import lombok.Data;
import org.springframework.stereotype.Component;@Data
@Component
public class Pet {private String name;private int age;
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.kuang</groupId><artifactId>springboot-01-helloworld</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-01-helloworld</name><description>springboot-01-helloworld</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencies><!-- 解决Person实体类使用注解@ConfigurationProperties报红 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>3.0.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

application.yml配置如下: 

name: helloworld
server:port: 8081person:name: wzxage: 28isWork: truebirth: 1997/12/12maps: {k1: v1, k2: v2}list:- coding- anime- ridingpet:name: 吉吉age: 7

Springboot01HelloworldApplicationTests单元测试类代码如下: 

package com.example;import com.example.pojo.Person;
import com.example.pojo.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class Springboot01HelloworldApplicationTests {@AutowiredPerson person;@Testvoid contextLoads() {System.out.println(person);}
}

运行单元测试类的方法后输出结果

@Test
void contextLoads() {System.out.println(person);
}

我们更改下application.yml配置文件的内容:

name: helloworld
server:port: 8081person:name: wzx${random.int}age: ${random.uuid}isWork: truebirth: 1997/12/12maps: {k1: v1, k2: v2}hello: ylllist:- coding- anime- ridingpet:name: ${person.hello:hello}_旺财 age: 7

我们重新查看下系统控制台的输出结果:

我们可以看到random.uuid产生的UUID,random.int产生的随机整数。以及另外一个特殊值${person.hello:hello}_旺财,它的含义是如果person.hello能取到值则显示该值并与字符串"_旺财"组合成新的字符串,否则给予默认值"hello",否并与字符串"_旺财"组合成新的字符串。

2.1. 松散绑定语法

示例代码如下,我们更改前面代码中的Pet实体类代码、application.yml配置类代码以及单元测试代码:

package com.example.pojo;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "pet")
public class Pet {private String firstName;private int age;
}
name: helloworld
server:port: 8081person:name: wzx${random.uuid}age: ${random.int}isWork: truebirth: 1997/12/12maps: {k1: v1, k2: v2}list:- coding- anime- ridingpet:name: ${person.hello:hello}_旺财age: 7pet:first-name: 很旺财

我们发现Pet实体类里属性命名为驼峰的firstName ,而yml里对应的是first-name,结果还是能匹配上,这便是yml的松散绑定机制。

package com.example;import com.example.pojo.Person;
import com.example.pojo.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class Springboot01HelloworldApplicationTests {@AutowiredPet pet;@Testvoid contextLoads() {System.out.println(pet);}
}

2.2. JSR303数据校验

本示例中通过验证email字段值的有效性,来体现yml对JSR303数据校验的支持:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.kuang</groupId><artifactId>springboot-01-helloworld</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-01-helloworld</name><description>springboot-01-helloworld</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>3.0.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

在maven的pom.xml文件中添加valdated的依赖spring-boot-starter-validation 

package com.example.pojo;import jakarta.validation.constraints.Email;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import java.util.Date;
import java.util.List;
import java.util.Map;/*** @ConfigurationProperties作用:* 将配置文件中配置的每个属性的值,映射到这个组件中* 告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定* 参数prefix = "person":将配置文件中的person下面的所有属性一一对应* 只有这个组件是容器中的组件,才能使用容器提供的ConfigurationProperties功能* 因此需要通过注解@Component来注册Bean*/
@Data
@Component
@ConfigurationProperties(prefix = "person")// 加载指定的配置文件
//@PropertySource(value = "classpath:wangzhexiao.properties")
@Validated // 数据校验
public class Person {
//    @Value("${personname}")private String name;@Email(message = "Email格式不对")private String email;private int age;private boolean isWork;private Date birth;private Map<String, Object> maps;private List<Object> list;private Pet pet;
}

Person类中增加数据校验注解 @Validated,并增加字段email和注解@Email

package com.example.pojo;import lombok.Data;
import org.springframework.stereotype.Component;@Data
@Component
public class Pet {private String firstName;private int age;
}
name: helloworld
server:port: 8081person:name: wzx${random.uuid}email: 王哲晓age: ${random.int}isWork: truebirth: 1997/12/12maps: {k1: v1, k2: v2}list:- coding- anime- ridingpet:name: ${person.hello:hello}_旺财age: 7

application.yml中增加email键值对 

package com.example;import com.example.pojo.Person;
import com.example.pojo.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class Springboot01HelloworldApplicationTests {@AutowiredPerson person;@Testvoid contextLoads() {System.out.println(person);}
}

运行后我们发现控制台抛出错误提示信息“Email格式不对”,这就是达到了JSR303数据校验的效果。

三、properties注入属性值到实体

properties配置文件在写中文的时候会有乱码,需要去IDEA中设置编码格式为UTF-8

package com.example.pojo;import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.List;
import java.util.Map;/*** @ConfigurationProperties作用:* 将配置文件中配置的每个属性的值,映射到这个组件中* 告诉springboot将本类中的所有属性和配置文件中相关的配置进行绑定* 参数prefix = "person":将配置文件中的person下面的所有属性一一对应* 只有这个组件是容器中的组件,才能使用容器提供的ConfigurationProperties功能* 因此需要通过注解@Component来注册Bean*/
@Data
@Component
//@ConfigurationProperties(prefix = "person")// 加载指定的配置文件
@PropertySource(value = "classpath:wangzhexiao.properties")
public class Person {@Value("${personname}")private String name;private int age;private boolean isWork;private Date birth;private Map<String, Object> maps;private List<Object> list;private Pet pet;
}
package com.example.pojo;import lombok.Data;
import org.springframework.stereotype.Component;@Data
@Component
public class Pet {private String name;private int age;
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.kuang</groupId><artifactId>springboot-01-helloworld</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-01-helloworld</name><description>springboot-01-helloworld</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>3.0.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

wangzhexiao.properties配置文件代码如下: 

personname=wzx

Springboot01HelloworldApplicationTests单元测试类代码如下: 

package com.example;import com.example.pojo.Person;
import com.example.pojo.Pet;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class Springboot01HelloworldApplicationTests {@AutowiredPerson person;@Testvoid contextLoads() {System.out.println(person);}
}

运行单元测试类的方法后输出结果

@Test
void contextLoads() {System.out.println(person);
}

四、配置文件位置及多环境配置

4.1. 配置文件位置

当四个配置文件位置都设置服务的端口并启动服务,会发现图片第1处的配置文件设置的端口生效。直到1、2、3处均不设置服务端口,4才会生效。这便是SpringBoot中关于配置文件位置的优先级。(yaml、yml或properties均是如此)

 

4.2. 多环境配置

4.2.1. 方式1

当有多个环境的配置文件时(默认、开发、测试等),application.yml(properties或yaml)配置文件生效。

 

我们可以通过配置spring.profiles.active来指定使某个环境的配置(application-后的名称)生效,这个配置必须设置在application.yml这个默认的配置文件中,设置到application-dev.yml、application-test.yml中无效。

 

 4.2.2. 方式2

在一个yml配置文件中设定多个环境的配置,中间用---区分隔开,多一个或少一个-都不行,这是SpringBoot规范,然后同样通过spring.profiles.active来激活指定环境的配置。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 美信监控易的优势:长期稳定运行
  • 让AI激发创作力:OpenAI分享5位专业作家利用ChatGPT写作的案例技巧
  • JSP 指令标识和脚本标识的使用
  • 828 华为云征文|华为 Flexus 云服务器搭建 SamWaf 开源轻量级网站防火墙
  • 快速搭建Kubernetes集群
  • SpringBoot3核心特性-核心原理
  • 【已解决】使用JAVA实现递归算法-从自然数中取3个数进行组合之循环算法
  • Vue3教程 - 1 Vue简介
  • JavaScript 网页设计案例详解( 最新技术趋势)
  • linux中怎么一次提交多条命令
  • BiRefNet 教程:基于 PyTorch 实现的双向精细化网络
  • word批量裁剪图片,并调整图片大小,不锁定纵横比
  • 付费电表系统的通用功能和应用过程参考模型(上)
  • 如何使用Optuna在PyTorch中进行超参数优化
  • OpenCV特征检测(12)检测图像中的潜在角点函数preCornerDetect()的使用
  • @jsonView过滤属性
  • 【Linux系统编程】快速查找errno错误码信息
  • 4. 路由到控制器 - Laravel从零开始教程
  • Angular 响应式表单之下拉框
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Linux Process Manage
  • Mocha测试初探
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • NSTimer学习笔记
  • Redis学习笔记 - pipline(流水线、管道)
  • Spring Cloud Feign的两种使用姿势
  • Swift 中的尾递归和蹦床
  • Tornado学习笔记(1)
  • tweak 支持第三方库
  • Vue实战(四)登录/注册页的实现
  • 关于Flux,Vuex,Redux的思考
  • 入门级的git使用指北
  • 提醒我喝水chrome插件开发指南
  • 消息队列系列二(IOT中消息队列的应用)
  • 携程小程序初体验
  • 用Visual Studio开发以太坊智能合约
  • 主流的CSS水平和垂直居中技术大全
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • !!Dom4j 学习笔记
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #100天计划# 2013年9月29日
  • $.ajax()方法详解
  • (8)STL算法之替换
  • (9)STL算法之逆转旋转
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (办公)springboot配置aop处理请求.
  • (超详细)语音信号处理之特征提取
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (三)终结任务
  • (生成器)yield与(迭代器)generator