SpringBoot:ch03 yml 数据绑定示例

news2024/11/15 14:10:25

前言

Spring Boot 提供了强大的配置能力,通过 YAML 文件进行数据绑定是一种常见且便捷的方式。在本示例中,我们将演示如何利用 Spring Boot 的特性,通过 YAML 文件实现数据绑定。借助于 YAML 的简洁语法和结构化特性,我们能够轻松地管理应用程序的配置信息,使得配置文件更加清晰易读。通过本示例,您将了解如何利用 Spring Boot 快速、高效地实现 YAML 数据绑定,为您的应用程序提供灵活且可维护的配置管理。让我们开始吧,深入探索 Spring Boot 中 YAML 数据绑定的精髓!

 

一、前期准备

1、新建项目,结构如下

2、导入依赖
<?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>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>edu.nf</groupId>
    <artifactId>ch03</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ch03</name>
    <description>ch03</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <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-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 这是一个 Maven 的 pom.xml 文件,它描述了一个 Spring Boot 项目的依赖关系和构建方式。

在这个文件中,我们定义了两个依赖项:

spring-boot-starter:这是一个 Spring Boot 的核心依赖,它包含了 Spring MVC、Spring Data JPA、Spring Security 等常用模块,并且自动配置了这些模块所需的环境。通过引入这个依赖,我们可以快速搭建一个基于 Spring Boot 的 Web 应用程序。

spring-boot-starter-test:这是一个 Spring Boot 的测试依赖,它提供了许多用于测试的工具和框架,例如 JUnit、Mockito、Hamcrest 等。通过引入这个依赖,我们可以轻松地编写和执行单元测试和集成测试。

此外,我们还定义了一个 Maven 插件 spring-boot-maven-plugin,用于将应用程序打包成一个可执行的 JAR 文件,以便于部署和运行。在这个插件中,我们还可以配置容器、端口等参数,以满足不同的应用程序需求。

总之,pom.xml 文件是 Spring Boot 项目的配置文件,它定义了项目的依赖关系和构建方式,并且通过 Maven 插件实现了对应用程序的打包和部署

 

二、第一种,值绑定

值绑定,使用 @value 注解精确指定节点的名称

1、新建一个 Student 类

@Component
@Data
public class Student {
    // 使用 @Value 注解和spell表达式将yml的节点值绑定到类的字段上
    @Value("${student.userId}")
    private Integer stuId;
    @Value("${student.userName}")
    private String stuName;
    @Value("${student.age}")
    private Integer age;
}

 这段代码是一个Spring组件,用于将YAML配置文件中的值映射到Java对象的字段上。

首先,使用了@Data注解,它会自动生成getter和setter方法、equals方法、hashCode方法以及toString方法。

然后,通过@Value注解来绑定YAML配置文件中的各个节点值到类的字段上。@Value注解中的"${student.userId}"等,是SpEL表达式,它会在运行时从YAML配置文件中读取对应节点的值,并将其赋值给类的字段。

例如,如果在YAML配置文件中有以下内容:

student:
 userId: 1001
 userName: qiu
 age: 18

那么在运行时,Student对象的stuId字段将被赋值为123,stuName字段将被赋值为"tom",age字段将被赋值为18。

总之,这段代码可以让你轻松地将YAML配置文件中的值映射到Java对象的字段上,方便你的代码使用。

2、测试

@SpringBootTest
@Slf4j
class Ch03ApplicationTests {

    @Autowired
    private Student student;

    @Test
    void contextLoads() {
        log.info(student.getStuId().toString());
        log.info(student.getStuName());
        log.info(student.getAge().toString());
    }

}

这段代码是一个Spring Boot的测试类,用于测试应用程序的上下文加载和配置是否正确。

首先,使用了@SpringBootTest注解,它表示这是一个Spring Boot的集成测试类。它会自动加载应用程序的上下文,并进行必要的配置。

然后,使用@Slf4j注解,它是Lombok库提供的注解,可以自动生成日志变量log。

接下来,通过@Autowired注解将Student对象注入到测试类中的student字段上。这样就可以在测试方法中使用该对象。

在contextLoads()方法中,通过调用student对象的getter方法,获取并打印stuId、stuName和age字段的值。这主要用于验证是否成功将YAML配置文件中的值绑定到Student对象的相应字段上。

通过日志输出,你可以在测试运行时查看stuId、stuName和age字段的值。

总结起来,这段代码用于测试Spring Boot应用程序的上下文加载和配置是否正确,并验证是否成功将YAML配置文件中的值绑定到相应的Java对象字段上。

 

运行结果:

三、第二种,松散绑定

使用 @ConfigurationProperties 注解,松散绑定只需要绑定指定节点的前缀即可,子节点在 yml 中可以依据约定, 使用驼峰模式(如:userName)、“—”线(如:允(user-name)、或者全大写加下划线(如:USER_NAME) 进行绑定即可。

1、还是使用 Student 类
​

@Component
@Data
@ConfigurationProperties(prefix = "student.info")
public class Student {
    private Integer stuId;
    private String stuName;
    private Integer age;
}

​

这段代码定义了一个名为 Student 的 Java 类,使用了 @Component@Data 注解,并且使用了 @ConfigurationProperties 注解对该类进行了配置。

@Component 注解表示这个类是 Spring 中的一个组件,会被 Spring 容器所管理。@Data 注解是 lombok 提供的注解,自动生成一些常用方法,如 gettersettertoString 等等。

@ConfigurationProperties(prefix = "student.info") 注解指定了该类的属性值从以 student.info 为前缀的配置项中获取。例如,配置文件中有如下配置:

# 数据值绑定
student:
  info:
    stuId: 1001
    stu-name: qiu
    AGE: 18

 则 Student 类中的 stuId 属性值为 1001stuName 属性值为 "qiu"age 属性值为 18

这里指定字段的格式我使用了三种,为的是演示可以这样去写,在实际开发中,大家最好是选择一种去使用,统一一点。

通过这种方式,我们可以将应用程序的配置信息与业务逻辑分离,使得配置文件更加清晰易读,同时也方便进行统一的配置管理。

测试的结果和值绑定到一样,就不测试了。需要注意的是,实体类的字段名称和yml配置的名称要一样,不能出现不一致的,不然会报错的。

2、绑定实体
1)新建一个 Card 实体类
@Data
public class Card {

    private String cardNum;

}

使用 @Data 生成 get、set访问器就可以了。

2)在 Student 实体类中引入 Card 实体类为字段
@Component
@Data
@ConfigurationProperties(prefix = "student.info")
public class Student {
    private Integer stuId;
    private String stuName;
    private Integer age;

    // 实体
    private Card card;
}

 在原有的 Student 类基础上,新增了一个名为 card 的属性,并且类型为 Card

yml示例:

# 数据值绑定
student:
  info:
    stuId: 1001
    stu-name: qiu
    AGE: 18
    card:
      card-num: 4408812000

 则 Student 类中的 stuId 属性值为 1001stuName 属性值为 "qiu"age 属性值为 18。Card类中的 cardNum 为 4408812000.

3)测试
@SpringBootTest
@Slf4j
class Ch03ApplicationTests {

    @Autowired
    private Student student;

    @Test
    void contextLoads() {
        log.info(student.getStuId().toString());
        log.info(student.getStuName());
        log.info(student.getAge().toString());
        log.info(student.getCard().getCardNum());
    }

}

在contextLoads()方法中,使用日志记录器log输出了student对象的一些属性信息。通过调用student对象的get方法获取学生的学号、姓名、年龄以及身份证号码,并通过log.info()方法将它们输出到日志中。 

运行结果:

 3、绑定数组
1)在 student 实体类中新建一个字段
  // 数组
    private String[] tels;

yml中绑定 tels 的值:

  # 绑定 array,list,set 集合,多个值使用逗号分隔
    tels: # 13223453421,14556766700
      - 13223453421
      - 14556766700

这里呢有两种写法,一种是用逗号隔开,一种是使用 “-”线加空格隔开,不加空格的话,输出的时候会把 “-” 也输出来。

2)测试
@SpringBootTest
@Slf4j
class Ch03ApplicationTests {

    @Autowired
    private Student student;

    @Test
    void contextLoads() {
        log.info(student.getStuId().toString());
        log.info(student.getStuName());
        log.info(student.getAge().toString());
        log.info(student.getCard().getCardNum());
        for (String tel : student.getTels()) {
            log.info(tel);
        }
    }

}

绑定了一个数组,拿出来只需要循环就可以啦。

运行结果:

4、绑定 map 
1)在 Student 实体类中新建一个字段
 // map
    private Map<String,Integer> score;

 yml 绑定 score 的值:

   # 绑定 map
    score:
      chinese: 85
      english: 60

 因为 map 是一以键值对保存数据的,所以这里的 Chinese 就是键,85 就是这个键的值。

 2)测试
@SpringBootTest
@Slf4j
class Ch03ApplicationTests {

    @Autowired
    private Student student;

    @Test
    void contextLoads() {
        log.info(student.getStuId().toString());
        log.info(student.getStuName());
        log.info(student.getAge().toString());
        log.info(student.getCard().getCardNum());
        for (String tel : student.getTels()) {
            log.info(tel);
        }
        student.getScore().forEach((k,v) -> log.info(k + " : " + v));
      
    }

}

Map的forEach()方法,遍历了getScore()返回的Map对象,并通过日志输出了每个键值对的内容。

运行结果:

5、复杂的值绑定
1)新建一个 Teacher 实体类
@Data
public class Teacher {

    private String name;
    private Integer age;

}
2)在 student 实体类中新加一个字段
 // 集合里面有个对象
    private List<Teacher> teaches;

yml绑定:


    # 绑定复杂类型(集合中包含对象)
    teaches:
      - name: Mr.qiu
        age: 21
      - name: Ms.zhi
        age: 22

这是一个 YAML 配置文件,其中 teaches 是一个复杂类型,包含了两个对象:Mr.qiuMs.zhi,它们都拥有 nameage 两个属性。

3)测试
 
@SpringBootTest
@Slf4j
class Ch03ApplicationTests {

    @Autowired
    private Student student;

    @Test
    void contextLoads() {
        log.info(student.getStuId().toString());
        log.info(student.getStuName());
        log.info(student.getAge().toString());
        log.info(student.getCard().getCardNum());
        for (String tel : student.getTels()) {
            log.info(tel);
        }
        student.getScore().forEach((k,v) -> log.info(k + " : " + v));
        student.getTeaches().forEach( teach -> {
            log.info(teach.getName());
            log.info(teach.getAge().toString());
        });
    }

}

 运行结果:

 

四、值绑定和松散绑定到优点和缺点

YAML 数据绑定的值绑定和松散绑定有以下优点:

  1. 简单易读:YAML 格式的数据配置文件相对于传统的属性文件更加简洁易读,且支持注释和多行文本。
  2. 灵活性:YAML 的灵活性允许我们在配置文件中使用复杂的数据类型,包括数组、对象、嵌套对象等。
  3. 易于维护:通过将配置文件中的值绑定到 Java 类上,我们可以使用 Java 对象的语法来访问这些值,使得代码更加易于维护和阅读。
  4. 配置管理:通过 @ConfigurationProperties 注解,可以将应用程序的配置信息与业务逻辑分离,使得配置文件更加清晰易读,同时也方便进行统一的配置管理。

但是,YAML 数据绑定的值绑定和松散绑定也有以下缺点:

  1. 学习成本:相比于传统的属性文件,使用 YAML 格式的数据配置文件需要学习新的语法和规则,需要一些时间来适应。
  2. 错误处理:由于 YAML 的松散绑定特性,当配置文件中出现错误时,可能会造成不可预知的结果,需要开发者自己注意检查和处理。
  3. 性能问题:相比于传统的属性文件,使用 YAML 格式的数据配置文件解析和读取速度可能会稍慢一些,特别是在处理大量数据时。

综上所述,在使用 YAML 数据绑定时,需要根据具体情况权衡其优缺点,并选择适合自己的方式来处理配置信息。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是神经网络(Neural Network,NN)

1 定义 神经网络是一种模拟人类大脑工作方式的计算模型&#xff0c;它是深度学习和机器学习领域的基础。神经网络由大量的节点&#xff08;或称为“神经元”&#xff09;组成&#xff0c;这些节点在网络中相互连接&#xff0c;可以处理复杂的数据输入&#xff0c;执行各种任务…

按照指定条件对数据进行分组并对每个分组内的全部数据应用自定义函数进行聚合计算groupby().apply()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 按照指定条件对数据进行分组 并对每个分组内的全部数据 应用自定义函数进行聚合计算 groupby().apply() [太阳]选择题 下列输出正确的是&#xff1a; import pandas as pd data {Name: [A, B,…

许战海战略文库|三步成就技术品牌:奥迪如何打造Quattro技术品牌?

引言&#xff1a;在当前全球化和信息化快速发展的背景下,技术品牌的打造不仅是企业竞争力提升的重要途径,也是企业实现长远发展的基石。技术品牌的建设并非一蹴而就的过程,而是需要企业准确把握市场趋势发掘自身核心竞争力,并通过长期的积累和推广逐渐在市场中树立起良好的技术…

『亚马逊云科技产品测评』活动征文|搭建Squoosh图片在线压缩工具

搭建Squoosh图片在线压缩工具 前言一、Squoosh是什么&#xff1f;二、准备一台Lightsail实例1.进入控制台2.创建实例3.开放端口4.部署Squoosh5.预览 三、搭建反向代理1. 安装宝塔2. 配置反向代理3. 预览代理效果 提示&#xff1a;授权声明&#xff1a;本篇文章授权活动官方亚马…

c++语言核心及进阶

核心编程 内存分区模型 根据c执行将内存划分为5个区域&#xff1a; 代码区&#xff0c;存放函数体的二进制&#xff0c;即CPU执行的机器指令&#xff0c;并且是只读的&#xff1b;常量区&#xff0c;存放常量&#xff0c;即程序运行期间不能被改变的量。全局区&#xff08;静…

断点检测学习

突然看到了一种反调试的手段&#xff0c;检测api函数的首字节是否为0xcc&#xff0c;即int 3类型的断点&#xff0c;来反调试&#xff0c;尝试一下 #include<stdio.h> #include<stdlib.h> void fun(int a) {a;a--;a 5;a - 5;return; } int main() {void (*ptr)(i…

Echarts+vue+java+mysql实现数据可视化

一、折线图&#xff0c;柱状图 https://echarts.apache.org/zh/index.html echarts 官网 更多配置项可以去官网查看 在开始项目之前&#xff0c;确保您已经安装了以下工具和技术&#xff1a; MySQL 数据库&#xff1a;用于存储和管理数据。Java 后端&#xff1a;用于创建后端应…

【JavaEE初阶】 JavaScript基础语法——壹

文章目录 &#x1f38b;初识JavaScript&#x1f6a9;JavaScript 是什么&#x1f6a9;JavaScript 和 HTML 和 CSS 之间的关系&#x1f6a9;JavaScript 运行过程&#x1f6a9;JavaScript 的组成 &#x1f38d;前置知识&#x1f6a9;第一个JS程序&#x1f6a9;JavaScript 的书写形…

【Docker】从零开始:3.Docker运行原理

【Docker】从零开始&#xff1a;3.Docker运行原理 Docker 工作原理Docker与系统的关系Docker平台架构图解 Docker 工作原理 Docker与系统的关系 Docker 是一个 Client-Server 结构的系统&#xff0c;Docker 守尹进程运行在王机上&#xff0c; 然后通过 Socket 连接从各尸端坊…

HCIP-一、RSTP 特性及安全

一、RSTP 特性及安全 实验拓扑实验需求及解法 实验拓扑 实验需求及解法 //1.SW1/2/3是企业内部交换机&#xff0c;如图所示配置各设备名称。 //2.配置VLAN&#xff0c;需求如下&#xff1a; //1&#xff09;SW1/2/3创建vlan10 [SW1]vlan batch 10 [SW2]vlan batch 10 [SW3]vla…

基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码

基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于卷尾猴优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

求二叉树中指定节点所在的层数(可运行)

运行环境.cpp 我这里设置的是查字符e的层数&#xff0c;大家可以在main函数里改成自己想查的字符。&#xff08;输入的字符一定是自己树里有的&#xff09;。 如果没有输出结果&#xff0c;一定是建树错误&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

【C++】C++11(2)

文章目录 一、新的类功能二、可变参数模板&#xff08;了解&#xff09;三、lambda表达式1. C98中的一个例子2.lambda表达式3.lambda表达式语法4.函数对象与lambda表达式 四、包装器1.function包装器2.bind 五、线程库1.thread类的简单介绍2.线程函数参数3.原子性操作库(atomic…

909-2014-T2

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 二叉树采用二叉链表存储结构&#xff0c;设计算法&#xff0c;判断二叉树是否为满二叉树。叙述算法思想并给出算法实现。 2.算法思想 通过一次遍历&#xff0c;得到结点个数和树的高度。用结点个数和树的高…

Spring Cloud实战 |分布式系统的流量控制、熔断降级组件Sentinel如何使用

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…

PowerShell无人参与安装最新版本SQL Server Management Studio (SSMS)

文章目录 下载SQL Server Management Studio (SSMS)Power Shell实现无人安装推荐阅读 下载SQL Server Management Studio (SSMS) SSMS 19.2 是最新的正式发布 (GA) 版本。 如果已经安装了 SSMS 19 预览版&#xff0c;需要在安装 SSMS 19.2 之前将其卸载。 如果安装了 SSMS 19.…

java io流中为什么使用缓冲流就能加快文件读写速度

FileInputStream的read方法底层确实是通过调用JDK层面的read方法&#xff0c;并且这个JDK层面的read方法底层是使用C语言编写的&#xff0c;以实现高效的文件读取功能。但是它会涉及多次内核态与操作系统交互。当我们使用FileInputStream的read方法读取文件时&#xff0c;首先会…

Java并发编程第12讲——cancelAcquire()流程详解及acquire方法总结

上篇文章介绍了AQS的设计思想以及独占式获取和释放同步状态的源码分析&#xff0c;但是还不够&#xff0c;一是感觉有点零零散散&#xff0c;二是里面还有很多细节没介绍到——比如cancelAcquire()方法&#xff08;重点&#xff09;&#xff0c;迫于篇幅原因&#xff0c;今天就…

[超详细]基于YOLO&OpenCV的人流量统计监测系统(源码&部署教程)

1.图片识别 2.视频识别 [YOLOv7]基于YOLO&#xff06;Deepsort的人流量统计系统(源码&#xff06;部署教程)_哔哩哔哩_bilibili 3.Deepsort目标追踪 &#xff08;1&#xff09;获取原始视频帧 &#xff08;2&#xff09;利用目标检测器对视频帧中的目标进行检测 &#xff08…

MAX/MSP SDK学习04:Messages selector的使用

其实消息选择器在simplemax示例中就接触到了&#xff0c;但这文档非要讲那么抽象。目前为止对消息选择器的理解是&#xff1a;可判断接收过来的消息是否符合本Object的处理要求&#xff0c;比如加法对象只可接收数值型的消息以处理&#xff0c;但不能接收t_symbol型的消息&…