JavaEE 进阶第十四期:Spring 容器背后的配置哲学


专栏:JavaEE 进阶跃迁营
个人主页:手握风云
目录
一、配置文件的作用
计算机上有数以千计的配置文件,我们使用的绝大多数软件,比如浏览器、微信、IDEA、Git、甚至手机都离不开配置文件。配置文件主要是为了解决硬编码带来的问题,硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中,也就是我们常说的"代码写死",把可能会发生改变的信息,放在一个集中的地方,当我们启动某个程序时,应用程序从配置文件中读取数据,并加载运行。比如说,我们在 IDEA 的设置里面修改字体的样式、大小、间距等。

SpringBoot支持并定义了配置文件的格式,也在另一个层面达到了规范其他框架集成到SpringBoot的目的。很多项目或者框架的配置信息也放在配置文件中,比如:项目的启动端口、数据库的连接信息。
二、快速上手配置文件
SpringBoot 内置了 Tomcat 服务器,默认端口是8080。但是⽤户电脑上8080端口号有可能就被其他应用程序占用了,所以 SpringBoot 需要支持让用户自定义端口号。SpringBoot 在创建项目时,就已经帮我们创建了配置文件。我们可以通过 application.properties 文件修改启动端口号,当我们再次启动这个 SpringBoot 项目时,就需要通过 。

server.port=8081
三、配置文件的格式
SpringBoot 的配置文件有以下三种:
- application.properties
- application.yml
- application.yaml
yml 是 yaml 的简写,使用方式一样,是一种类似 html 的文件,实际开发中频率最高。
server: port: 8082
当应用程序启动时,SpringBoot 会自动从 classpath 路径中找到并加载配置文件。同一个配置项,如果 properties 和 yml 同时配置了,properties 优先级更高。
四、properties 配置文件说明
properties 配置文件是最早期的配置文件格式,也是创建 SpringBoot 项目默认的配置文件。
4.1. properties 基本语法
properties 是以键值的形式配置的,key和value之间是以"="连接的,如:
# 配置项目端口号 server.port=8080 #配置数据库连接信息 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&useSSL=false spring.datasource.username=root spring.datasource.password=root4.2. 读取配置文件
如果想要主动的读取配置文件中的内容,可以使用 @Value 注解来实现。 注解使用 @Value("${}") 的格式读取,如下代码所示:
package com.yang.test1_30_1; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/prop") public class PropertiesController { @Value("${spring.datasource.url}") private String url; @Value("${my.key1}") private Integer key1; @Value("${my.key2}") private Boolean key2; @RequestMapping("/read") public String readProperties() { System.out.println(key1); System.out.println(key2); return "从配置文件中,读取url" + url; } }spring.application.name=Test1_30_1 server.port=8081 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&useSSL=false spring.datasource.username=root spring.datasource.password=root my.key1=5 my.key2=true 
4.3. properties 缺点分析
properties 配置文件以 key-value(键值对) 形式进行配置,其核心缺点是存在大量冗余信息,具体表现如下:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&useSSL=false spring.datasource.username=root spring.datasource.password=root可见配置的 key 中,spring.datasource 这一前缀会重复出现多次,此类重复内容即为冗余信息,增加了配置文件的编写成本与维护复杂度。
还有一点需要注意:如果我们在 application.properties 里面加入了一些中文注释,当我们关闭项目之后再次打开,就会出现乱码。我们只需使用快捷键 ctrl + alt + s 打开 IDEA 的设置,把下面两个地方改成 UTF-8 即可。

五、yml 配置文件说明
5.1. yml 基本语法
yml 是树形结构的配置文件,它的基础语法是 "key: value"。key 和 value 之间使用英文冒号和空格组成,并且空格不能省略。
#单层 yaml yaml: aa # 多层 yaml sping: datasource: url: jdbc:mysql://127.0.0.1:3306/testdb? username: root password: root5.2. yml 进阶
1. yml 配置不同数据及 null
# 字符串 string.value: Hello # 布尔值 boolean.value1: true boolean.value2: false # 整数 int.value: 10 # 浮点数 float.value: 3.14 # Null null.value: ~获取配置的方式与 propertiese 的方式一样,都是使用 @Value 注解。
package com.yang.test1_31_1; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/yaml") @RestController public class YamlController { @Value("${yaml}") private String yaml; @Value("${spring.datasource.username}") private String username; @RequestMapping("/read") public String read() { System.out.println(yaml); System.out.println(username); return "success"; } }2. 配置对象
student: id: 1 name: 18 age: 21这里想要获取配置,需要使用另外一个注解 @ConfigurationProperties 来读取。
package com.yang.test1_31_2; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @Configuration @ConfigurationProperties(prefix = "student") @Data public class Student { private Integer id; private String name; private Integer age; }package com.yang.test1_31_2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/yaml") @RestController public class TestController { @Autowired private Student student; @RequestMapping("/read") public void read() { System.out.println(student); } }
3. 配置集合
集合的读取和对象的方式一样。
dbtypes: name: -mysql -sqlserver -db1package com.yang.test1_31_3; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import java.util.List; @Configuration @ConfigurationProperties(prefix = "dbtypes") @Data public class DbType { private List<String> name; }package com.yang.test1_31_3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/yaml") public class TestController { @Autowired private DbType dbType; @RequestMapping("read") public String read() { System.out.println(dbType); return "success"; } }
4. 配置 map
maptypes: map: k1: aaa k2: bbb k3: cccpackage com.yang.test1_31_4; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; import java.util.Map; @Configuration @ConfigurationProperties(prefix = "maptypes") @Data public class MapConfig { private Map<String, String> map; }package com.yang.test1_31_4; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/yaml") public class TestController { @Autowired private MapConfig mapConfig; @RequestMapping("/read") public String read() { System.out.println(mapConfig); return "success"; } }5.3. yml 优缺点
一、优点
- 可读性与易用性佳:写法简单直观,采用树形结构,降低了理解成本,便于开发和维护时快速获取配置信息。
- 支持更多数据类型:可轻松表达对象、数组、List、Map 等多种数据形态,能更灵活地满足项目中不同结构的配置需求,无需像 properties 格式那样重复书写冗余的键前缀。
- 跨语言兼容性强:不仅可在 Java 中使用,还支持 Golang、Python、Ruby、JavaScript 等多种编程语言,适用范围更广,便于多语言协作的项目统一配置风格。
二、缺点
- 不适合复杂配置场景:面对复杂配置(如多层嵌套、多维度关联的配置,文档中以 keycloak 相关配置为例),转换为 yml 格式时需花费较多精力,且配置层级过多后可读性会显著下降,代码编写难度也随之增加。
- 格式要求严格:对语法格式(如 key 与 value 间需加英文冒号和空格、层级缩进等)有极强的约束性,微小的格式错误(如缺少空格、缩进不一致)就可能导致配置加载失败,即文档中提到的 “一个空格可能会引起一场血案”。