Spring Boot 学习之路 -- 配置项目

前言

  1. 最近因为业务需要,被拉去研究后端的项目,代码框架基于 Spring Boot,对我来说完全小白,需要重新学习研究…
  2. 出于个人习惯,会以 Blog 文章的方式做一些记录,文章内容基本来源于「 Spring Boot 从入门到精通(明日科技) 」一书,做了一些整理,更易于个人理解和回顾查找,所以大家如果希望更系统性的学习,可以阅读此书(比较适合我这种新手)。

一、Spring Boot 项目的配置文件

程序开发人员在开发 Spring Boot 项目的过程中,会发现 Spring Boot 非常好用。这是因为 Spring Boot 项目所需要的数据都在其配置文件中完成了配置。配置文件中的数据有很重要的作用。例如,如果在一个 Spring Boot 项目的配置文件中缺少关于数据库的数据,这个 Spring Boot 项目就无法连接、操作数据库。在一个 Spring Boot 项目的配置文件中,有些数据在创建这个 Spring Boot 项目时就完成了配置,有些数据则需要程序开发人员进行配置。

下面就介绍程序开发人员如何对 Spring Boot 项目的配置文件中的数据进行配置。

当创建一个 Spring Boot 项目时,就会在其中的 src/main/resources 目录下自动创建一个 application.properties 文件,该文件就是这个 Spring Boot 项目的配置文件。

在这里插入图片描述

程序开发人员在配置 Spring Boot 项目的过程中,会在配置文件中配置该项目所需的数据信息。这些数据信息被称作“配置信息”。那么,“配置信息”都包含哪些内容呢?“配置信息”的内容非常丰富,这里仅举例予以说明:

  • Tomcat服务器
  • 数据库的连接信息,即用于连接数据库的用户名和密码
  • Spring Boot 项目的启动端口
  • 第三方系统或者接口的调用密钥信息
  • 用于发现和定位问题的日志

我们回顾一下【Spring Boot 学习之路 – 基础认知】 中第一个 Spring Boot 程序,会发现并没有对这个程序做任何配置,仅编写了几行代码,这个程序就能够实现一个简单的跳转功能。其实,这就凸显了 Spring Boot 的强大之处:当创建一个 Spring Boot 项目时,有些配置信息就已经在配置文件中被配置完成了,不需要程序开发人员予以配置,这提高了开发程序的效率。

下面将先对配置文件的格式予以介绍。

1.1 配置文件的格式

Spring Boot 支持多种格式的配置文件,最常用的是 properties 格式(默认格式)和比较新颖的 yaml/yml 格式。下面将分别介绍这两种格式的特点。

properties

properties 格式是经典的键值对文本格式。也就是说,如果某一个配置文件的格式是 properties 格式,那么这个配置文件的文本格式为键值对。

键值对的语法非常简单,具体如下:

key=value​​

= 左侧为键(key),= 右侧为值(value)。

在配置文件中,每个键独占一行。如果多个键之间存在层级关系,就需要使用“父键.子健”的格式予以表示。

例如,在配置文件中,为一个有三层关系的键赋值的语法如下:

​​​​key1.key2.key3=value​​

例如,启动 Spring Boot 项目的 Tomcat 端口号为 8080,那么在这个项目的 application.properties 文件中就能够找到如下的内容:

​​​​server.port=8080​​

启动这个项目后,即可在控制台看到如下一行日志:

o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)

这行日志表明 Tomcat 根据配置开启的是 8080 端口。

在 application.properties 文件中,“#” 被称作注释符号,用于向文件中添加注释信息。例如:

​​​​# Tomcat端口
​​​​server.port=8080​​

yaml/yml

yml 是 YAML 的缩写,和 yaml 一样,它是一种可读性高的用于表达数据序列化的文本格式。yml 格式的配置文件的文本格式也是键值对。只不过,键值对的语法与 Python 语言中的键值对的语法非常相似,具体如下:

​​​​key: value​​

注意:

英文格式的 “:” 与值之间至少有一个空格。

英文格式的 “:” 左侧为键(key),英文格式的 “:” 右侧为值(value)。需要注意的是,英文格式的 “:” 与值之间只能用空格缩进,不能用 Tab 缩进;空格数量表示各层的层级关系。

例如,在配置文件中,为一个有三层关系的键赋值的语法如下:

key1:
​​​​ key2:
​​​​  key3: value​​

在 properties 格式的配置文件中,即使父键相同,在为每一个子健赋值时也要单独占一行,还要把父键写完整,例如:

​​​​com.spark.strudent.name=tom
​​​​com.spark.strudent.age=21​​

但是在 yaml 格式的配置文件中,只需要编写一次父键,并保证两个子健缩进相同即可。例如,把上述 properties 格式的键值对修改为 yaml 格式的键值对:

​​​​com:
​​​​ spark:
​​​​  student:
​​​​   name: Tom
​​​​   age: 21​​

对于 Spring Boot 项目的配置文件,不论是采用 properties 格式,还是采用 yaml 格式,都由程序开发人员自行决定。但是,在同一个 Spring Boot 项目中,尽量只使用一种格式的配置文件;否则,这个 Spring Boot 项目中的 yaml 格式的配置文件将被忽略掉。

1.2 达成约定的配置信息

虽然程序开发人员可以在配置文件中自定义配置信息,但是 Spring Boot 也有一些已经达成约定的配置信息。这些配置信息用于设置 Spring Boot 项目的一些属性,具体如下:

# Tomcat 使用的端口号
server.port=808080

# 配置 context-path
server.servlet.context-path=/

# 错误页地址
server.error.path=/error

# session 超时时间(分钟),默认为 30 分钟
server.servlet.session.timeout=60

# 服务器绑定的 IP 地址,如果本机不在此 IP 地址则启动失败
server.address=192.168.1.1

# Tomcat 最大线程数,默认为 200
server.tomcat.threads.max=100

# Tomcat 的 URI 字符编码
server.tomcat.uri-encoding=UTF-8

二、读取配置信息的值

程序开发人员如果已经在配置文件中保存了一些自定义的配置信息,那么在编码时应该如何读取这些配置信息的值呢?为此,Spring Boot 提供了 3 种读取方法。下面将对其分别予以介绍。

2.1 使用 @Value 注解读取值

@Value 注解可以向类的属性注入常量、Bean 或者配置文件中配置信息的值。使用 @Value 注解读取配置信息的值的语法下:

​​​​@Value("${key}")​​

例如,读取 Tomcat 开启的端口号,代码如下:

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

我们在工程中测试一下:

  1. 在 application.properties 配置文件中添加:
com.spark.name=HanMeiMei
com.spark.age=18
com.spark.gender=\u5973

这 3 行内容分别对应:姓名、年龄和性别。

  1. 修改 BeanTestController:
@RestController
public class BeanTestController {
    @Value("${com.spark.name}")
    private String name;

    @Value("${com.spark.age}")
    private Integer age;

    @Value("${com.spark.gender}")
    private String gender;

    @RequestMapping("/people")
    public String getPeople() {
        String result = "<li>名称:" + name + "</li>" +
                "<li>名称:" + age + "</li>" +
                "<li>名称:" + gender + "</li>";
        System.out.println(gender);
        System.out.println(gender);
        System.out.println(gender);
        return result;
    }
}
  1. 运行,看看效果:

在这里插入图片描述

如果使用 @Value 读取一个不存在的配置信息的值,例如:

​​​​@Value("${com.mr.school}")
​​​​private String school;​​

那么,启动项目后将抛出如下的异常信息:

Could not resolve placeholder 'com.spark.school' in value "${com.spark.school}"

这个异常信息的含义是:程序无法找到与“com.mr.school”相匹配的值。因此,在使用@Value读取配置文件中的配置信息的值时,一定要确保配置信息的名称是存在的,并且是正确的。

2.2 使用 Environment 环境组件读取值

如果配置文件中的配置信息经常需要修改,那么为了能够读取配置信息的值,就需要使用一个更为灵活的方法,即 org.springframework.core.env.Environment 环境组件接口。这是因为即使 Environment 环境组件接口尝试读取一个不存在的配置信息的值,程序也不会抛出任何异常信息。

Environment 环境组件接口的对象是由 Spring Boot 自动创建的,程序开发人员可以直接注入并使用它。

Environment对象注入的方式如下:

​​​​@Autowired
​​​​Environment env;​​

Environment 环境组件接口提供了丰富的 API,下面列举几个常用的方法:

​​​​containsProperty(String key);​​
  • key:配置文件中配置信息的名称。
  • 返回值:如果配置文件存在名为 key 的配置信息,则返回 true,否则返回 false。
​​​​getProperty(String key)​​
  • key:配置文件中配置信息的名称。
  • 返回值:配置文件中 key 对应的值。如果配置文件中没有名为 key 的配置信息,则返回 null。
getProperty(String key, Class<T> targetType)​​
  • key:配置文件中配置信息的名称。
  • targetType:方法返回值封装成的类型。
  • 返回值:配置文件中 key 对应的值,并封装成 targetType 类型。
​​​​getProperty(String key, String defaultValue);​​
  • key:配置文件中配置信息的名称。
  • defaultValue:默认值。
  • 返回值:配置文件中 key 对应的值,如果配置文件中没有名为 key 的配置信息,则返回 defaultValue。

注意:

如果配置文件中存在某个配置信息,但等号右侧没有任何值(如 “name=”),那么 Environment 组件会认为这个配置信息存在,并且这个配置信息的值为空字符串。

我们看下在 BeanTestController 里面怎么使用,代码如下:

@RestController
public class BeanTestController {
    @Autowired
    Environment environment;

    @RequestMapping("/environment")
    public String getPeople() {
        StringBuilder result = new StringBuilder();
        if (environment.containsProperty("com.spark.name")) {
            String name = environment.getProperty("com.spark.name");
            result.append("<li>姓名:").append(name).append("</li>");
        }
        if (environment.containsProperty("com.spark.age")) {
            int age = Integer.parseInt(Objects.requireNonNull(environment.getProperty("com.spark.age")));
            result.append("<li>年龄:").append(age).append("</li>");
        }
        String school = environment.getProperty("com.spark.school", "XX 学院");
        result.append("<li>学校:").append(school).append("</li>");
        String language = environment.getProperty("com.spark.language", "C++");
        result.append("<li>所学语言:").append(language).append("</li>");
        return result.toString();
    }
}

运行看下效果:

在这里插入图片描述

2.3 使用映射类的对象读取值

除了 @Value 注解和 Environment 环境组件,Spring Boot 还提供了用于声明映射类的 @ConfigurationProperties 注解。下面就对其予以介绍。

说明:

用于封装配置信息的类被称作映射类。

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

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

相关文章

python-4-4-编程规范2

str1 ,str2 input("请输入两个学生的姓名&#xff0c;用空格分开").split() print(str1) print(str2)print("hello python")name "Jim" print("His name is :",name)a "hello" b "python" print(a,b)print(&q…

ResNet50V2:口腔癌分类

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 ResNet和ResNetV2对比 改进点&#xff1a;(a)original表示原始的ResNet的残差结构&#xff0c;(b)proposed表示新的ResNet的残差结构&#xff0c;主要差别就是(a)结构先卷积后进行BN和激活函数…

原生app云打包,更换图标,和名称。PDA的安装正式包

原生app云打包 复制下载即可&#xff0c;是正式版

Python批量处理客户明细表格数据,挖掘更大价值

批量处理 .xls 数据并进行归类分析以挖掘内在价值&#xff0c;通常涉及以下步骤&#xff1a; 读取数据&#xff1a;使用 pandas 库读取 .xls 文件。数据清洗&#xff1a;处理缺失值、异常值、重复值等。数据转换&#xff1a;对数据进行必要的转换&#xff0c;如日期格式统一、…

yolo自动化项目实例解析(七)自建UI--工具栏选项

在上一章我们基本实现了关于预览窗口的显示&#xff0c;现在我们主要完善一下工具栏菜单按键 一、添加工具栏ui 1、配置文件读取 我们后面要改的东西越来越多了&#xff0c;先加个变量文件方便我们后面调用 下面我们使用的config.get意思是从./datas/setting.ini文件中读取关键…

RP2040 C SDK GPIO和IRQ 唤醒功能使用

RP2040 C SDK GPIO和中断功能使用 SIO介绍 手册27页&#xff1a; The Single-cycle IO block (SIO) contains several peripherals that require low-latency, deterministic access from the processors. It is accessed via each processor’s IOPORT: this is an auxiliary…

PHP基础知识

一、PHP变量&#xff1a; 变量是用于存储信息的"容器" <?php$x5;$y6;$z$x$y;echo $z; ?> 在 PHP 中&#xff0c;这些$字母被称为变量。 PHP 变量 变量可以是很短的名称&#xff08;如 x 和 y&#xff09;或者更具描述性的名称&#xff08;如 age、carname、…

【Java异常】(简简单单拿捏)

【Java异常】&#xff08;简简单单拿捏&#xff09; 1. 异常的简单介绍2. 异常的抛出2.1 语法 3. 异常的处理3.1 异常声明throws3.2 try-catch捕获并处理 4. 例子&#xff08;try-catch自定义异常&#xff09; 1. 异常的简单介绍 程序员在运行代码时会遇到很多异常&#xff0c…

学习threejs,绘制二维线

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言二、&#x1f340;绘制二维线1. ☘️…

基于Hive和Hadoop的保险分析系统

本项目是一个基于大数据技术的保险分析系统&#xff0c;旨在为用户提供全面的汽车保险信息和深入的保险价格分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark…

2016年国赛高教杯数学建模A题系泊系统的设计解题全过程文档及程序

2016年国赛高教杯数学建模 A题 系泊系统的设计 近浅海观测网的传输节点由浮标系统、系泊系统和水声通讯系统组成&#xff08;如图1所示&#xff09;。某型传输节点的浮标系统可简化为底面直径2m、高2m的圆柱体&#xff0c;浮标的质量为1000kg。系泊系统由钢管、钢桶、重物球、…

SpringBoot使用EasyPoi根据模板导出word or pdf

1、导出效果 1.1 wrod 1.2 pdf 2、依赖 <!--word--><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.3.0</version></dependency><dependency><groupId>cn.…

探讨TikTok直播专线的必要性

随着社交媒体的迅速发展&#xff0c;短视频平台如TikTok&#xff08;在中国抖音&#xff09;已成为现代人生活中不可或缺的一部分。TikTok的直播功能因其即时性和互动性受到广泛喜爱&#xff0c;但在中国市场上&#xff0c;主播们在使用这一功能时面临不少挑战&#xff0c;其中…

优选拼团平台架构解析与关键代码逻辑概述

一、系统架构设计 唐古拉优选拼团平台采用多层架构设计&#xff0c;主要包括前端展示层、业务逻辑层、数据访问层及数据存储层。 前端展示层&#xff1a;负责用户界面的展示和交互&#xff0c;包括商品列表、拼团详情、订单管理等页面。前端采用现代前端框架&#xff08;如Vue…

【Linux】图解详谈HTTPS的安全传输

文章目录 1.前置知识2.只使用对称加密3.只使用非对称加密 因为私钥加密只能公钥解开&#xff0c;公钥加密只能私钥解开4.双方都是使用非对称加密5.非对称加密 对称加密6.非对称加密对称加密CA认证&#xff08;一&#xff09;CA认证&#xff08;二&#xff09;https &#xff0…

信息学奥赛的最佳启蒙阶段是小学还是初中?

信息学奥赛&#xff08;NOI&#xff09;近年来越来越受家长和学生的关注&#xff0c;尤其是在编程教育不断升温的背景下&#xff0c;信息学竞赛成为了许多家庭的教育选择之一。家长们往往关心的是&#xff1a;孩子应该在什么年龄段开始接触信息学竞赛&#xff0c;才能打下坚实的…

ArcEngine C#二次开发图层处理:根据属性分割图层(Split)

需求&#xff1a;仅根据某一属性&#xff0c;分割图层&#xff0c;并以属性值命名图层名称保存。 众所周知&#xff0c;ArcGIS ArcToolbox中通过Split可以实现图形分割一个图层&#xff0c;以属性值命名图层&#xff0c;如下图所示。 本文仅仅依据属性值&#xff0c;将一个shp…

统信服务器操作系统【qcow2 镜像空间扩容】方案

使用 qcow2 镜像安装系统,当默认安装系统存储空间不够用时,进行自定义扩容 文章目录 准备环境扩容步骤一、检查环境信息1.查看镜像信息2.查看镜像分区信息3.确认需要扩容的分区名二、扩容1.备份镜像2.创建新的镜像文件,并指定空间3.将系统扩容到新的镜像三、扩容 lvm 分区四…

自然语言处理实战项目:从理论到实现

一、引言 自然语言处理&#xff08;NLP&#xff09;是计算机科学、人工智能和语言学交叉的领域&#xff0c;旨在让计算机能够理解、处理和生成人类语言。随着互联网的飞速发展&#xff0c;大量的文本数据被产生&#xff0c;这为自然语言处理技术的发展提供了丰富的素材&#xf…

从响应到预见:前瞻性客户服务策略的实践与探索

在快速变化的商业环境中&#xff0c;客户服务已不再是简单的需求响应与问题解决&#xff0c;它正逐步演变为企业竞争力的核心要素之一。传统的“响应式”服务模式虽能满足基本的客户需求&#xff0c;但在追求极致客户体验和构建长期忠诚度的今天&#xff0c;显然已显不足。因此…