JavaEE进阶 - Spring Boot 配置文件 - 细节狂魔

x33g5p2x  于2022-07-26 转载在 Java  
字(7.2k)|赞(0)|评价(0)|浏览(314)

1、配置文件作用

整个项目中所有重要的数据都是在配置文件中配置的。
比如:
1、数据库的连接信息(包含用户名和密码的设置)
2、项目的启动端口
3、第三方系统的调用密钥等信息
4、用于发现和定位问题的普通日志 和 异常日志 等。
5、还可以配置 日志的级别(规定只显示达到某个级别的日志),以及日志的持久化存储。

想象一下:
如果没有配置信息,那么 Spring Boot 项目就不能连接和操作数据库,甚至是不能保存可以用于排查问题的关键日志,所以配置文件的作用是非常重要的!

举个例子:
之前我在讲 Servlet项目:博客系统 的时候,我们需要去写关于 MySQL 的 JDBC 代码,其涉及到的 用户名密码,还有数据源,这些信息都是保存一个叫做 DBUtil 的自定义类中。
而一个正儿八经的 Spring Boot 项目,不会将这些重要的,敏感的信息,放在代码里面的!
因为你放在代码里面的话,它是不方便去修改的。
并且,只能是我们程序员去改!

试想=一下:
在一个正儿八经的公司里,技术岗位是有很多种的!
假设我们是开发人员,那我们只是负责开发部分的工作。
最终项目的部署,是程序员部署的吗?还是测试人员去部署的?

都不是,测试 是 负责 测试环境,开发是负责开发环节。
而生产环境,是由另一种技术人员:运维工程师来负责的!
运维工程师,是需要修改我们项目中的配置文件的。

运维工程师懂 JAVA 代码 吗?
他不懂的!
运维工程师,他们的能力点 在于:他们对 Linux 服务器 非常熟悉!
对于那些常见的木马,漏铜,他们具有相应的排查手段 和 解决方案!
他们对于 “安全性” 方面的知识,是知道的比较多!

总的来说:
运维工程师,主要就是部署项目,并且让项目能够在服务器上,稳定的运行。

一个项目开发完了,我们开发人员的工作就完成了。
接下来,项目就会交给测试部门。
测试部门测试完了之后,项目功能都没问题。
说明 项目 可以上线了。
那么,测试部门就会把 项目包 交给 运维部门,由运维来进行项目的部署。

也就是说:
你如果把 配置文件 写到 代码里(项目包里),有以下几个问题:
1、运维人员是不懂 Java 的,他没办法去修改代码。
即使 这个 运维人员,懂 Java,但是!想想 我们 Spring Boot 打包的是一个什么 包?
是一个 jar 包,对不对?俩面存储的都是 .class 文件(二进制文件)。
而我们是把信息写到 一个类,经过编译生成的文件,就是 .class 文件。
二进制文件,你能改吗??
你改不了的!!!
字节码文件,是只能看,不能修改的!!!

但如果我们将信息写到 配置文件中,运维是可以修改配置文件的。

像配置文件中信息,一般都是 key - value 的形式,运维是看得懂的。
而且,在改完之后,按住它,拖回到包,再替换。
这就完成修改了。

这就是为什么,将重要信息都写在配置文件中,应为被人可以改。
这是 配置文件的一个优点。

配置文件还有一个优点:

配置文件可以设置 开发环境 和 配置环境,两个配置文件。
然后呢,在运行打包的时候,通过修改一个变量,就可以指定 当前项目 “走”哪一个配置文件。
所以,配置文件之间是可以并存的!
意思就是:
可以将两个,或两个以上的配置文件(开发的,测试的,运维的),项目上线的时候,我们只需要改一个参数,改一个名字。
然后,项目中所有的内容,全部都会走 另一个配置文件。非常方便!
到时候,会给你们演示一下。

另外,再补充一点。
配置文件的分类,里面的内容可以分为两个类:
1、系统级别的
2、自定义级别的

配置文件中,可以存储第三方系统的调用密钥等信息。
这个第三方,假设指的是一款软件。
我们的项目,也可以说是一块软件。
现在,这两款软件,有业务交流。
那么,我们项目中的配置文件,就需要在 配置问价 设置 相关信息。
就好比拥有了一把 “钥匙”,通往 第三方软件,一次来获取需要的信息。

当前请注意!并不是所有的软件,都需要和这个第三方软件,建立关系。
因此,配置文件 设置的信息,是我们项目独有的,是自定义的!

而在前一篇博客SpringBoot 的 概念、创建和运行,我就将一个“约定大于配置”的例子。
扫描的根目录,是有系统默认指定的。

2、配置文件的格式

Spring Boot 配置⽂件主要分为以下两种格式:
1、.properties
2、.yml
【文件的后缀代表着文件的格式;配置文件也是如此!!!】

至于为什么要有两种格式?

这两者之间的关系,就像前面讲Bean 作用域 和 生命周期中的 @PostConstruct 与 init- method 之间的关系一样。
两者的功能是一样的,但是!是来自于 两个不同时间段 的 产物。

最早出现的配合文件格式是 .properties。
然后,在后期的使用中发现: properties 存在着一些缺陷。
那么,自然就会产生一个想法:properties 该怎么去优化?
于是,.yml 格式的配置文件,就诞生了。
这就和 maven 和 gradle 之间的关系一样。
gradle 是 maven 的升级版。
我们的 .yml格式的配置文件,就是 .properties格式配置文件 的 升级版。

前面讲过:一个项目中,可以存在多个配置文件。
即:配置文件之间是可以共存的!

也就是说:我们可以直接在项目中传建其他的配置文件,格式可以不同!

下面我们看看,对配置文件进行设置之后,会有什么效果

1、application.properties 配置文件 - 效果演示

我们先来回顾一下:上篇文章中,关于启动项目,验证项目是否能正常运行的代码。【输出一个 hello world】

而此时!不同的是:我们将 Tomcat 的服务器的端口修改了。
改成 8081 了。【在演示配置文件可修改的时候,做出的修改。】

下面,我们就爱尝试一下:
1、继续使用8080端口号,是否能访问到 sayHi 方法。
2、使用 8081 端口号,是否能访问到 sayHi 方法。

但是!请注意!
配置文件的名称是固定的,是认死了的!
这就是我们接下来要展示的第二个约定:配置文件名,只能是 application!
如果改成其它的名称。配置文件的内容,将不再生效。

2、application.yml 配置文件 - 效果演示

虽然,applications.properties 配置失效了。
但是!我们还有一个 application.yml 的配置文件。
它也是可以进行设置的。

同时也体现出了 配置文件之间是可以共存的。
applications.properties 配置文件失效了,但是 application.yml 有效。

此时,我们来 搞事情!
将 applications.properties 配置文件,改回去。
applications >> application。

现在,我们来运行一下程序,看看它执行的是哪个配置文件。

这里,讲一个规则:

1、一个项目中可以存在两种格式的配置文件(properties 和 yml),但是不建议一个项目中出现两种格式的配置文件。
因为:如果两者混用,需要要求 程序员 对 这两种格式的配置文件,都了解。
这样会提高整个公司里的开发人员的门槛,
如果程序员只了解这两个格式的配置文件中的一个格式(比如 yml),他就想不通!
为什么我的 yml 格式的配置文件不生效?
这样会拖慢开发的速度。
同时也增加了 维护的难度。

如果一个项目里,统一使用一种格式的配置文件,就不会出现这样的问题!
就算有问题,也不用考虑 :是否是 存在 两种格式的配置文件原因。
而且,方便查看 和 维护。

举个例子:
这个跟 开 奶茶店一样,同一个品牌的奶茶。
它们的员工服装,店面装修的特色,都是统一。
有的朋友,甚至不用看 店的招牌,看到员工的服装 和 店面的装修,就知道了这家是那个品牌。
Idrink,荧光绿,CoCo(都可) 层黄,一点点:墨绿 + 白色。。。。。
像这种“统一”的特色,让我们对它印象非常深刻。更容易识别。

2、当一个项目的某个配置,出现在两种格式的配置文件中时,那么配置项会以properties 为主(忽略 yml 中的配置)。

为配置⽂件安装提示插件 - 社区版 idea

IDEA 社区版安装 Spring Assistant 插件之后,就可以正常创建 Spring Boot 项⽬了,并且 yml 的配置⽂件就有提示了。
但默认情况下是不⽀持 properties 格式的⽇志提示的,这个时候需要安装了 Spring Tools 插件才会有相应的提示。

application.properties 配置文件说明

application properties 配置文件是最早期的配置文件格式,也是创建 Spring Boot 项目的默认的配置文件。
这一点,在我们创建好 Spring Boot 项目的时候,就已经体现出来了。
因为 application.properties 配置文件,是项目创建好之后,就自带了的。

properties 基本语法

properties 是以 键值 的形式配置的,key 和 value 之间是以 “=” 连接的。
如:

而且!
在填写完后面的 value 值 之后,也不能加上一个空格。
会出事!!!
比如:
设置端口号:

另外,我们还可以自定义键值对。【上面的是系统级别的配置】

这里还存在一个问题:
当设置好了之后,重新启动idea 打开配置文件的时候,这里的 注释的中文,会变成乱码。

这是因为 application.properties 是属于早期的配置文件,而早期的 配置文件是不支持中文的。
而 yml 是天生就支持中文的(utf8)。
要想 application.properties 支持中文,需要进行配置。

还没完,上述操作只是针对当前项目。
那么,新项目呢?当然也需要配置!

如果还是乱码!
将原来的 application.properties 配置文件删除掉,重新创建一个 application.properties。
因为之前的配置文件已经是不支持中文编码的文件格式化。而设置的编码集,只是作用于 后面新创建的文件。
所以,删掉,重新创建一个,是最有效的方法。
后面,就不用我们去设置了。
因为我们已经针对新建项目,进行设置了。

查看更多系统配置项 - properties

想要查看 Spring Boot 更多系统配置项,访问官⽹:https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties

不要求全部记下来,用的时候去查一下,就行了。

读取配置⽂件 - propertices

到了 Spring Boot 时代,几乎所有的功能,都可以通过 注解来搞定。
读取配置文件也是一样的,
可以使⽤ @Value 注解来实现。
@Value 注解使⽤“${}”的格式读取.
书写的格式 和 属性注入 是一样的。
创建一个变量,使用 @Value 注解,将对应的配置信息 通过 类似于 属性注入的方式,来获取。
@Value 注解 通过会搭配参数(“${server.port}”)使用。
里面的参数,就是获取配置信息 “键”。【注入的就是对应的 value值】

我们来启动项目,看看效果。

通过上述方法,就可以获取到 application.properties 配资文件中的信息。
那 application.yml 呢??

properties 格式配置文件的 缺点分析

想要解决这个问题,就可以使⽤ yml 配置⽂件的格式化了。
下面,我门先来熟悉一下 yml ,

application.yml 配置⽂件说明

yml 是 YAML 是缩写,它的全称 Yet Another Markup Language 翻译成中⽂就是“另⼀种标记语⾔”。

yml 是⼀个可读性⾼,易于理解,⽤来表达数据序列化的格式。它的语法和其他⾼级语⾔类似(与 json 格式类似,键值对之间使用冒号+空格,进行分隔),并且可以简单表达清单(数组)、散列表,对象,标量,布尔,int等数据形态,甚至连 null 都可以设置!!!

它使⽤空⽩符号缩进和⼤量依赖外观的特⾊,特别适合⽤来表达或编辑数据结构、各种配置⽂件等。

yml 最⼤的优势是可以跨语⾔,不⽌是 Java 中可以使⽤。
golang、python 都可以使⽤ yml 作为配置⽂件。
大厂一般都是分公司,每个子公司的技术中心都是不同(使用的技术不同)。
就是说:每个公司 主要使用的 语言 和 框架,都是由它们自己决定的。
比如:
字节跳动,主要是使用 go 语言,但是并不代表 其它语言 就不使用了。
有的部分可能使用是 java,有的可能 Pyhton。
此时,配置文件的跨语言性,就非常重要!
想象一下:
我们的这些语言,不管你使用的是哪种语言。
我们在进行读取数据的时候,数据都是共享的。

试想一下:
字节跳动产品有很多,但是它们的用户是互通的。
这么说吧:
假设:
我们用手机号 在 今日头条 上注册了一个账号。
那么,在抖音,西瓜视频,等等。。字节跳动的产品中,账号信息是互通的。
j再来假设一下:
今日头条是go做的,抖音是Java做的,西瓜视频是Python,而用户的数据只有一份。
想象也能明白:
都是一个平台的产品,用户数据共用一份不好吗?
也就是说:这些产品连接的数据库,都是一样的。
那么,数据库这里的连接,都是由谁搞的呢?
由运维去搞的。

那好,如果它使用的都是一套配置文件。
那么,运维只需要撘一个 在线的配置文件。
一般公司项目的配置文件,都不会存储在本地的。
因为,存储在本地,就会存在 配置文件 泄露的问题。
大家都是使用的配置中心,这个配置中心会将 所有的配置文件,都配置到自身内部的某一个包底下。
然后,这些项目可以直接去连接 远程在线的 配置中心,将配置文件拉取到 本地。
这样就会有一个好处:
即使 服务器被人攻占了, 项目的jar包 被人偷走,但是 jar 包 里面没有 本地的配置信息的。即使拿到了 jar 包,也是运行不了的。

回过头来,此时,也就是说:
一个大公司,它使用的语言不止一种的。
这时候,有一套 跨语言的配置文件,是非常重要的!
因为有了 这个跨语言的配置文件后,就可以让不同的开发者(Java,Go,Python。。。),都可以通过使用这份配置文件,去连接数据库了。
不用再去为每一种语言,都去设置一个配置文件。
因为我一份配置文件,其它语言都可以使用。

总结下来, yml 配置文件一共有三个优点:
1、写法简单
2、支持多种数据类型
3、支持跨语言

上述这三个优点,都是 properties 配置文件所不具备的。

yml 基本语法

yml 是树形结构的配置⽂件,它的基础语法是“key: value”,注意 key 和 value 之间使⽤英⽂冒号加空格的⽅式组成的,其中的空格不可省略。

yml的优点:解决 properties的缺点问题(代码冗余度高)。

yml 使⽤进阶:yml 配置不同数据类型及 null

# 字符串
string.value: Hello
# 布尔值,true或false
boolean.value: true
boolean.value1: false
# 整数
int.value: 10
int.value1: 0b1010_0111_0100_1010_1110 # ⼆进制
# 浮点数
float.value: 3.14159
float.value1: 314159e-5 # 科学计数法
# Null,~代表null
null.value: ~

读取配置⽂件 - yml

拓展:注意事项

value 值加单双引号 - yml配置文件中,关于数据的单双引号的问题。

由此,不难得出结论:
在 yml 中,如果使用了 双引号就会按照原语义执行。
如果不加 单,双引号,或者加了 单引号,那么默认会将字符串中的 特殊字符 进行转义。
比如: \n -> \ \n
关于 单双引号的用法,请根据实际情况来选择使用。
如果你想所见即所得,就直接不加 单,双引号,即可。

如果你想按照原语义执行,得到其运行的结果。
使用 双引号 包裹起来即可。

配置对象 - yml 配置文件

前面不是提到过 yml 支持 更丰富的 数据类型嘛。
现在我们就来讲这个。

读取对象 - yml 配置对象

有的人脑子转的比较快,马上就想到了 “解决方法”。
直接去创建一个 相应的对象,然后使用 @Value 注解 进行 “属性注入”,不就行了嘛!
我们来试试。

下面我们来分析一下错误原因 error

这是因为:想要 获取 配置文件中的 对象 所使用的注解,不是 @Vlaue注解。
而是,通过给 Student类 添加一个@ConfigurationProperties 注解, 来读取 配置文件中的对象。
并且设置一个 属性(选项)值 prefix = “student”

读李四的数据,只要将 @ConfigurationProperties的 prefix 属性值修改一下就可以了。【重新弄一个新的,也行】

配置集合 - yml

读取集合 - yml

集合的读取和对象⼀样,也是使⽤ @ConfigurationProperties 来读取的,具体实现如下:

Properties VS yml 总结

1、properties 是以 key=value 的形式配置的键值类型的配置⽂件.
⽽ yml 使⽤的是类似 json 格式的树形配置⽅式进⾏配置的.
yml 层级之间使⽤换⾏缩进的⽅式配置,key 和 value 之间使⽤“: ”(英⽂)冒号加空格的⽅式设置,并且空格不可省略。

2、properties 为早期并且默认的配置⽂件格式,但其配置存在⼀定的冗余数据,使⽤ yml 可以很好的解决数据冗余的问题。

3、yml 通⽤性更好,⽀持更多语⾔,如 Java、Go、Python 等,如果是云服务器开发,可以使⽤⼀份配置⽂件作为 Java 和 Go 的共同配置⽂件。

4、yml 虽然可以和 properties 共存,但⼀个项⽬中建议使⽤统⼀的配置类型⽂件。

拓展:Spring Boot 有几种读取配置文件的方法?

Spring Boot 中 读取配置文件有以下 5 种方法:
1、使用 @Value 注解 读取配置文件(仅限单个信息,集合和对象除外)
2、使用 @ConfigurationProperties 注解 来读取配置文件。
3、使用 Environment 读取配置文件

4、使用 @PropertySource 读取配置文件(可能会用到)

5、使用原生方式读取配置文件

前2种,可以解决 读取配置配置文件的 90% 的问题。
其余三种,知道有这么个东西就行。

相关文章