第2章 Spring Boot配置体系
技术栈:Spring Boot 4.1.1 + JDK 17 本章定位:配置是Spring Boot的核心骨架,从端口调整、数据库连接、功能开关到多环境部署,全部基于配置体系完成。
学习目标
- ✅ 掌握
properties和YAML两种配置格式,能正确编写、互相转换,避开YAML语法坑 - ✅ 掌握三种配置读取方式:
@Value、Environment、@ConfigurationProperties,知道各自适用场景 - ✅ 会用
@PropertySource加载自定义配置、@ImportResource兼容XML配置、@Configuration+@Bean编写Java配置类 - ✅ 熟练掌握Profile多环境配置,会用多种方式切换环境
- ✅ 理解配置优先级、敏感信息处理、外置配置等企业级规范
- ✅ 能独立排查配置不生效、读取失败、中文乱码等常见问题
2.1 全局配置文件
2.1.1 配置文件概述
Spring Boot的核心设计思想是**「约定大于配置」**:框架提前约定了绝大多数场景的默认值,90%的情况你不用写任何配置,项目就能跑起来。只有需要修改默认行为时,才去全局配置文件里覆盖对应配置项。
Spring Boot启动时,会自动从src/main/resources目录下加载全局配置文件,支持两种格式:
application.properties:传统键值对格式application.yml/application.yaml:YAML结构化格式
⚠️ 优先级规则:
- 同目录下同时存在时,
properties > yml > yaml,高优先级的同名配置会覆盖低优先级的- 不同的配置项会合并生效,不会互相覆盖
配置分为三类:
| 类型 | 示例 | 说明 |
|---|---|---|
| Spring Boot内置配置 | server.port、spring.datasource.url | 框架自带的配置项,修改即可改变框架行为 |
| 第三方Starter配置 | mybatis.mapper-locations | 引入的第三方启动器提供的配置项 |
| 自定义业务配置 | app.upload-path | 开发者自己定义的配置,代码中读取使用 |
💡 新手提示:不用死记所有配置项,常用的记几个,其余用到的时候查官方文档即可。
官方配置参考:https://docs.spring.io/spring-boot/docs/4.1.1/reference/htmlsingle/#application-properties
2.1.2 application.properties 详解
.properties是Java原生的配置格式,采用key=value的扁平结构,一行一个配置。
基础语法
# ===== 字符串 =====
# 注释用#号开头,默认不用加引号
app.name=springboot-demo
app.description=这是一个Spring Boot项目
# ===== 数字 =====
server.port=8080
app.max-connections=100
# ===== 布尔值 =====
app.enable-cache=true
app.debug=false
# ===== 对象/Map =====
# 用.分隔层级
user.id=1001
user.name=张三
user.age=25
user.email=zhangsan@example.com
# ===== 数组/List =====
# 写法1:逗号分隔
user.hobbies=读书,跑步,编程
# 写法2:按索引赋值
user.hobbies[0]=读书
user.hobbies[1]=跑步
user.hobbies[2]=编程优缺点
- ✅ 优点:格式简单,所有Java项目都兼容
- ❌ 缺点:配置多了之后,前缀大量重复,层级不清晰,可读性差
2.1.3 application.yml 详解(重点⭐)
YAML(YAML Ain't Markup Language)用空格缩进表示层级关系,结构清晰,是目前企业新项目的主流格式。
🔴 新手必记:四大语法铁则(错一个配置都不生效)
key: value冒号后面必须加空格,没空格直接失效- 只能用空格缩进,绝对不能用Tab键,同一层级必须左对齐
- 大小写敏感,
Name和name是两个完全不同的key #开头表示注释
❌ 新手头号坑:YAML语法错误不会报错!配置静默失效,启动不报错但就是读不到值,90%的配置问题都是缩进和空格的锅。
错误示例 vs 正确示例
❌ 错误写法(典型新手错误)
server:
port:8080 # 错误:port没缩进;冒号后面没空格
name:demo # 错误:name缩进和port不对齐✅ 正确写法
server:
port: 8080
name: demo基础语法示例
1. 字面量
# 字符串,默认不用加引号
app:
name: springboot-demo
description: 这是一个Spring Boot项目
# 数字
server:
port: 8080
# 布尔值
app:
enable-cache: true引号说明:
- 单引号
' ':转义特殊字符,比如'\n'会被当成普通字符串\n- 双引号" ":不转义特殊字符,比如
"\n"就是换行- 普通场景直接写,不用加引号
2. 对象/Map
# 缩进式(推荐,结构清晰)
user:
id: 1001
name: 张三
age: 25
email: zhangsan@example.com
# 行内式(适合简单对象)
user: {id: 1001, name: 张三, age: 25}3. 数组/List
# 缩进式(推荐)
user:
hobbies:
- 读书
- 跑步
- 编程
# 行内式
user:
hobbies: [读书, 跑步, 编程]注意:短横线
-前面要有缩进,后面必须加空格。
4. 多层嵌套(真实项目写法)
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: 123456
redis:
host: localhost
port: 6379
timeout: 3000
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true在线转换工具
复杂配置写完,可以用工具校验格式,避免缩进错误:
- JSON转YAML:https://www.bairesdev.com/tools/json2yaml/
- YAML转JSON:https://transform.tools/yaml-to-json
2.1.4 配置文件位置与优先级
Spring Boot启动时,会从5个位置扫描配置文件,优先级从高到低,高优先级覆盖低优先级的同名配置:
| 优先级 | 位置 | 说明 |
|---|---|---|
| 1(最高) | file:./config/ | JAR包同级目录下的config子目录(外部配置) |
| 2 | file:./ | JAR包所在的同级目录(外部配置) |
| 3 | classpath:/config/ | resources下的config目录(内部配置) |
| 4(最低) | classpath:/ | resources根目录(我们开发默认放的位置) |
企业级实践:外置配置文件
生产环境通常把配置文件放在JAR包外面,改配置不用重新打包,这是企业部署的标准操作。
目录结构:
myapp/
├── config/
│ └── application.yml # 外部配置,优先级更高
└── myapp.jar # 可执行JAR包启动的时候直接java -jar myapp.jar,会自动优先读取外部config目录下的配置。修改配置只需要改外部文件,重启即可生效。
🔒 安全红线: 生产环境的数据库密码、第三方密钥等敏感信息,绝对不能写在代码里,也不能提交到Git。一般由运维人员管理外部配置文件,开发人员不接触生产环境密码。
2.2 配置绑定:代码中读取配置
配置写好之后,怎么在Java代码里读取使用?主流有三种方式,各有适用场景。
2.2.1 @Value 注解(单个配置注入)
最简单的单个配置项注入,适合零散少量配置。
基础用法
package com.example.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component // 必须交给Spring管理,不然注解不生效!
public class AppConfig {
// 读取内置配置server.port
@Value("${server.port}")
private Integer port;
// 读取自定义配置app.name
@Value("${app.name}")
private String appName;
}设置默认值(必学⭐)
配置不存在的时候,给一个默认值,用冒号:分隔,避免启动报错。
// app.name不存在时,默认值为default-app
@Value("${app.name:default-app}")
private String appName;
// 数字默认值
@Value("${app.max-connections:100}")
private Integer maxConnections;⚠️ 新手踩坑:
@Value("${app.name}")如果配置文件里没有app.name,会直接抛出PlaceholderResolutionException,项目启动失败!所以写@Value建议都加上默认值。
支持SpEL表达式
支持Spring表达式语言,可以做简单运算、调用方法:
// 生成随机数
@Value("#{T(java.lang.Math).random() * 100}")
private Double randomNum;
// 字符串分割
@Value("#{'${user.hobbies}'.split(',')}")
private String[] hobbies;优缺点
| ✅优点 | ❌缺点 |
|---|---|
| 简单直接,单个配置注入方便 | 配置多的时候代码繁琐 |
| 支持SpEL表达式 | 不支持批量绑定、不支持JSR303校验 |
| 复杂对象注入麻烦 |
🎯 适用场景:只需要读取少量零散配置项的时候。
package com.example.demo.controller;
@RestController
@RequestMapping("/test")
public class ConfigTestController {
// 注入我们写的配置类
@Autowired
private AppConfig appConfig;
@GetMapping("/config1")
public String getConfig1() {
return "读取到的配置:" +
"port=" + appConfig.getPort() +
", appName=" + appConfig.getAppName();
}
}2.2.2 Environment 对象(动态读取)
Spring内置的环境配置接口,可以动态获取配置。
基础用法
package com.example.controller;
import org.springframework.core.env.Environment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController {
@Autowired
private Environment env;
@GetMapping("/config2")
public String getConfig2() {
// 获取配置,带默认值
String port = env.getProperty("server.port", "8080");
// 判断配置是否存在
boolean hasKey = env.containsProperty("app.name");
// 获取当前激活的环境
String[] profiles = env.getActiveProfiles();
return "port=" + port + ", activeProfile=" + profiles[0];
}
}常用方法
| 方法 | 说明 |
|---|---|
getProperty(key) | 获取配置值,返回String,不存在返回null |
getProperty(key, defaultValue) | 获取配置,带默认值 |
getRequiredProperty(key) | 获取配置,不存在直接抛异常 |
containsProperty(key) | 判断配置是否存在 |
getActiveProfiles() | 获取当前激活的所有profile |
适用场景
- 配置key是动态的,运行时才能确定
- 工具类、非Spring管理的类中获取配置
- 偶尔读取少量配置,不想专门写配置类
💡 注意:业务代码不要大量写
env.getProperty(),会导致代码散乱。一组相关配置优先用@ConfigurationProperties。
2.2.3 @ConfigurationProperties 注解(批量绑定⭐企业推荐)
Spring Boot官方推荐方式,批量把一组配置绑定到Java对象,支持松散绑定、数据校验,企业项目首选。
基础示例
- 配置文件
application.yml
book:
book-name: SpringBoot实战
price: 79
author: 广州华商职业学院
tags:
- Java
- SpringBoot- 配置类
@Data // 自动生成getter/setter,必须有!
@Component // 交给Spring容器管理
@ConfigurationProperties(prefix = "book") // 指定配置前缀
public class BookConfig {
private String bookName;
private Integer price;
private String author;
private List<String> tags;
}- 使用
@RestController
public class BookController {
@Autowired
private BookConfig bookProperties;
@GetMapping("/book")
public BookConfig getBook() {
return bookProperties;
}
}⚠️ 必须有setter方法!Spring通过setter注入属性。用Lombok的
@Data会自动生成,不用手写。

松散绑定(Relaxed Binding)
配置名和Java字段名不需要完全一致,自动匹配多种命名风格:
| 配置写法 | Java字段名 | 能否匹配 |
|---|---|---|
book.bookName | bookName(驼峰) | ✅ |
book.book-name | bookName(短横线kebab-case) | ✅ |
book.book_name | bookName(下划线snake_case) | ✅ |
book.BOOK_NAME | bookName(全大写下划线) | ✅ |
✅ 官方推荐规范:配置文件用短横线式(
book-name),Java代码用驼峰式(bookName)。
JSR303数据校验
支持配置值合法性校验,项目启动时就校验,提前暴露配置错误,避免线上出问题。
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>- 配置类加校验
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
@Data
@Component
@Validated // 开启校验
@ConfigurationProperties(prefix = "user")
public class UserProperties {
@NotBlank(message = "用户名不能为空")
private String username;
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
@Email(message = "邮箱格式不正确")
private String email;
}配置不符合规则时,项目启动直接报错,把问题拦在启动阶段。
IDEA配置提示增强
写自定义配置没有自动提示?加上配置处理器依赖,IDEA会自动补全:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>2.2.4 三种方式对比与选型
| 对比项 | @Value | Environment | @ConfigurationProperties |
|---|---|---|---|
| 注入方式 | 字段上注解 | 对象注入 | 类上注解,批量绑定 |
| 适用场景 | 单个零散配置 | 动态获取配置 | 一组相关配置,结构化管理 |
| 松散绑定 | ❌不支持 | — | ✅支持 |
| JSR303校验 | ❌不支持 | ❌不支持 | ✅支持 |
| SpEL表达式 | ✅支持 | ❌不支持 | ❌不支持 |
| 代码量 | 配置多时繁琐 | 适中 | 配置多时简洁 |
📌 选型口诀:
- 少量零散配置:用
@Value- 动态key、工具类:用
Environment- 一组相关配置、需要校验:优先用
@ConfigurationProperties
2.3 自定义配置文件与配置类
默认application.yml是全局配置,配置多了可以按模块拆分,也可以兼容老项目的XML配置。
2.3.1 @PropertySource 加载自定义properties配置
把配置按模块拆分,加载自定义的.properties文件。
使用示例
- 在
resources下新建user.properties
user.id=1001
user.nickname=法外狂徒张三- 配置类加载
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Data
@Component
@PropertySource("classpath:user.properties") // 加载自定义配置文件
@ConfigurationProperties(prefix = "user")
public class UserProperties {
private String id;
private String nickname;
}注意事项
classpath:表示从类路径(resources目录)下查找- 可以引入多个文件:
@PropertySource({"classpath:a.properties", "classpath:b.properties"}) - ❗ 原生不支持加载YAML文件,只能加载properties。4.x推荐统一放在主yml中用前缀区分模块。
2.3.2 @ImportResource 引入XML配置
兼容传统Spring的XML配置文件,老项目迁移用,新项目不推荐。
使用示例
resources下新建beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myService" class="com.example.service.MyService"/>
</beans>- 启动类引入XML
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
@SpringBootApplication
@ImportResource("classpath:beans.xml") // 引入XML配置
public class Chapter02Application {
public static void main(String[] args) {
SpringApplication.run(Chapter02Application.class, args);
}
}适用场景
- 老项目迁移到Spring Boot,XML配置太多一时改不完
- 第三方框架只提供XML配置方式
✅ 最佳实践:新项目全部用Java配置类(
@Configuration + @Bean),不要写XML;老项目逐步迁移,不要长期混用。
2.3.3 @Configuration 配置类(Java配置,推荐⭐)
用Java代码做配置,替代XML配置文件,是Spring Boot推荐的方式。
基础用法
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // 标记这是一个配置类
public class MyConfig {
// 把方法返回值注册到Spring容器,Bean名默认是方法名
@Bean
public MyService myService() {
return new MyService();
}
}等价于XML:
<bean id="myService" class="com.example.service.MyService" />
@Bean进阶用法
- 指定Bean名称
@Bean(name = "customService")
public MyService myService() {
return new MyService();
}- 指定初始化/销毁方法
@Bean(initMethod = "init", destroyMethod = "destroy")
public MyService myService() {
return new MyService();
}- 注入依赖
@Configuration
public class MyConfig {
@Bean
public UserDao userDao() {
return new UserDao();
}
@Bean
public UserService userService(UserDao userDao) {
UserService service = new UserService();
service.setUserDao(userDao);
return service;
}
}
一、简化目录结构示例
src/main/java/com/example/demo/
├── DemoApplication.java # 启动类
├── config/
│ └── MyConfig.java # ⭐ Java配置类
├── service/
│ └── MyService.java # 业务类
└── controller/
└── TestController.java # 测试验证二、核心代码
1. 业务类 MyService.java
package com.example.demo.service;
public class MyService {
public void sayHello() {
System.out.println("Java配置类注册Bean成功!");
}
}2. 配置类 MyConfig.java(核心)
package com.example.demo.config;
import com.example.demo.service.MyService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // 标记:这是Java配置类
public class MyConfig {
// @Bean:把方法返回值注册到Spring容器,Bean名默认=方法名
@Bean
public MyService myService() {
return new MyService();
}
}✅ 等价 XML:
<bean id="myService" class="com.example.demo.service.MyService" />
3. 测试控制器
package com.example.demo.controller;
import com.example.demo.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired // 自动注入注册好的Bean
private MyService myService;
@GetMapping("/testBean")
public String test() {
myService.sayHello();
return "配置类测试成功,查看控制台";
}
}三、验证
启动项目,访问:http://localhost:8080/testBean 控制台打印Java配置类注册Bean成功!,就说明配置生效。
Java配置类 vs XML配置
| 对比项 | XML配置 | Java配置类 |
|---|---|---|
| 写法 | XML标签 | Java代码+注解 |
| 类型安全 | 运行时才发现错误 | 编译期就能检查 |
| 重构友好 | 改类名需手动改XML | IDE重构自动修改 |
| 调试 | 不方便 | 可打断点调试 |
| 复杂逻辑 | 不支持 | 支持 |
🎯 面试题:Spring Boot推荐XML还是Java配置类? 答:推荐Java配置类(
@Configuration + @Bean),类型安全、重构友好、便于调试。XML也支持,通过@ImportResource引入,主要用于兼容老项目。
2.4 Profile多环境配置(企业必备⭐⭐⭐)
项目从开发到上线,要经过开发、测试、生产多个环境,每个环境配置不一样。Profile机制实现「一套代码,多套配置」,切换环境只需改一个参数。
2.4.1 为什么需要多环境
| 环境 | 标识 | 特点 |
|---|---|---|
| 开发环境 | dev | 本地开发调试,本地数据库、详细日志、热部署 |
| 测试环境 | test | 测试人员功能验证,测试数据库、模拟数据 |
| 生产环境 | prod | 线上正式运行,生产数据库、性能优化、安全加固 |
2.4.2 多文件多Profile(企业主流推荐)
每个环境一个独立配置文件,结构清晰,企业最常用。
命名规则
application.yml # 主配置:公共配置 + 指定激活环境
application-dev.yml # 开发环境
application-test.yml # 测试环境
application-prod.yml # 生产环境格式:
application-{profile名}.yml
完整示例
- 主配置
application.yml
spring:
application:
name: chapter02-demo
profiles:
active: dev # 默认激活开发环境- 开发环境
application-dev.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: root
password: 123456
logging:
level:
com.example: debug- 生产环境
application-prod.yml
server:
port: 80
spring:
datasource:
url: jdbc:mysql://生产IP:3306/prod_db
username: prod_user
password: 生产密码
logging:
level:
com.example: info四种切换方式(优先级从高到低)
- 命令行参数(生产部署最常用)
java -jar myapp.jar --spring.profiles.active=prod- JVM系统参数
java -Dspring.profiles.active=prod -jar myapp.jar- 操作系统环境变量(Linux服务器常用)
export SPRING_PROFILES_ACTIVE=prod
java -jar myapp.jar- 配置文件(开发时用)
spring:
profiles:
active: prod🏢 企业最佳实践:
- 代码里默认激活
dev环境,方便开发- 生产环境用命令行参数指定,不把生产配置写死在代码里
- 生产环境配置文件不提交Git,防止密码泄露
验证当前环境
写个接口快速验证当前激活的环境:
@GetMapping("/profile")
public String getActiveProfile() {
String[] profiles = environment.getActiveProfiles();
return "当前激活环境:" + Arrays.toString(profiles);
}2.4.3 @Profile注解(Bean级环境控制)
指定某个Bean只在特定环境下才注册生效。
示例
- 定义接口
public interface SmsService {
void sendMsg(String phone);
}- 开发环境实现
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile("dev") // 仅dev环境生效
public class DevSmsService implements SmsService {
@Override
public void sendMsg(String phone) {
System.out.println("【开发模拟】发送短信到:" + phone);
}
}- 生产环境实现
@Component
@Profile("prod") // 仅prod环境生效
public class ProdSmsService implements SmsService {
@Override
public void sendMsg(String phone) {
// 真实调用第三方短信接口
}
}- 使用
@RestController
public class SmsController {
@Autowired
private SmsService smsService; // 自动注入当前环境的实现
@GetMapping("/sms")
public String send() {
smsService.sendMsg("13800138000");
return "发送完成";
}
}进阶用法
- 取反:
@Profile("!dev")表示非dev环境才生效 - 多环境:
@Profile({"dev", "test"})表示dev和test环境都生效
2.4.4 单文件多Profile(了解)
同一个YAML文件用---分隔不同环境,适合个人小项目。
# 公共配置
spring:
application:
name: demo
profiles:
active: dev
---
# 开发环境
spring:
config:
activate:
on-profile: dev
server:
port: 8080
---
# 生产环境
spring:
config:
activate:
on-profile: prod
server:
port: 80缺点:配置多时文件臃肿,多人协作容易冲突,适合个人小项目。
2.5 配置进阶:企业级实践
2.5.1 配置优先级全解
Spring Boot配置来源众多,优先级从高到低:
| 优先级 | 来源 | 说明 |
|---|---|---|
| 1(最高) | 命令行参数 | java -jar app.jar --server.port=8080 |
| 2 | JVM系统属性 | java -Dserver.port=8080 -jar app.jar |
| 3 | 操作系统环境变量 | 服务器上配置的环境变量 |
| 4 | 外部配置文件 | JAR包外config目录下的配置 |
| 5 | 内部配置文件 | JAR包内resources下的配置 |
| 6 | @PropertySource引入的配置 | 自定义加载的配置文件 |
| 7(最低) | 框架默认值 | Spring Boot自动配置的默认值 |
🛠 排查配置不生效第一步:先检查有没有更高优先级的配置覆盖了!
2.5.2 敏感信息处理
生产环境数据库密码、第三方密钥等敏感信息,不能明文写在配置文件里,更不能提交Git。
常见处理方案
- 环境变量(最简单) 配置文件引用环境变量:
spring:
datasource:
password: ${DB_PASSWORD}服务器上设置环境变量:
export DB_PASSWORD=生产密码- 配置中心(推荐) 用Nacos、Apollo等配置中心统一管理,敏感信息加密存储、权限控制、动态刷新。微服务阶段常用。
- 配置加密(jasypt) 配置文件里写加密后的密文,启动时用密钥解密。适合配置文件需要随项目分发的场景。
⚠️ 安全红线:绝对不要把生产环境密码提交到Git! 即使删除文件,历史记录里依然存在。一旦泄露立即修改密码。
2.5.3 配置中心简介
项目多了之后,配置分散在各个项目里管理困难,配置中心解决统一管理、动态刷新、权限控制、版本管理、加密存储等问题。
常见配置中心:
- Nacos:阿里巴巴出品,功能全,配置中心+注册中心,国内应用最广
- Apollo:携程出品,治理能力强,大型企业用得多
- Spring Cloud Config:Spring官方,轻量,配合Git使用
了解即可,微服务阶段会详细学习,先建立概念。
2.6 常见问题排查清单
1. 配置不生效
排查步骤:
- 检查文件名:必须是
application.yml/application.properties,拼写错误、大小写错误都不行 - 检查位置:默认必须在
resources根目录 - 检查YAML语法:冒号后有空格、只用空格缩进、同一层级对齐(最常见)
- 检查优先级:有没有更高优先级的配置覆盖
- 检查拼写:注意松散绑定规则,大小写敏感
- 开启debug模式,查看自动配置报告
2. @ConfigurationProperties不生效
排查:
- 类上有没有
@Component/@Configuration,必须被Spring管理 prefix是否和配置前缀一致- 字段名和配置名是否匹配(松散绑定规则)
- 有没有setter方法(Lombok @Data会自动生成)
- 启动类有没有扫描到配置类
3. 多环境切换不生效
排查:
- profile名称拼写是否正确(dev/test/prod)
- 配置文件名是否正确:
application-dev.yml,横杠、后缀不要写错 - 激活配置是否写在主配置文件里
- 有没有更高优先级的激活方式(比如命令行参数)
4. 配置中文乱码
解决:
- IDEA设置:
Settings → Editor → File Encodings,Properties文件编码设为UTF-8,勾选「Transparent native-to-ascii conversion」 - 配置文件指定编码:
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true5. @Value注入失败
排查:
- 类有没有交给Spring管理(加@Component)
- 配置key是否存在,有没有拼写错误
- 是不是写成了
@Value("name"),漏掉了$和大括号 - 配置文件位置不对
2.7 本章作业(动手实操+思考题)
一、基础必做题(全员必做,必须跑通验证)
作业1:配置格式转换
题目:将下面properties配置转换成标准YAML格式,保存为application.yml
server.port=8081
spring.application.name=chapter02-homework
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/homework
spring.datasource.username=root
spring.datasource.password=root123
book.book-name=SpringBoot入门实战
book.price=68
book.tags=Java,SpringBoot,后端要求:
- 缩进正确,层级清晰
- 用在线转换工具校验格式正确性
- 启动项目,验证端口变为8081
作业2:三种读取配置练习
题目:
- 在
application.yml中配置自定义student前缀的配置:姓名、年龄、邮箱、爱好(数组) - 分别用三种方式读取配置:
@Value读取姓名,设置默认值Environment动态读取年龄@ConfigurationProperties批量绑定全部字段,加上JSR303校验
- 编写Controller接口,返回读取到的全部配置数据
- 浏览器访问验证三种方式都能正确读取
验收标准:
- 接口返回所有配置值正确
- 故意写错邮箱格式,项目启动报错,证明校验生效
作业3:Java配置类练习
题目:
- 创建
DemoUtil工具类,编写一个printInfo()方法 - 用
@Configuration + @Bean的方式将DemoUtil注册到Spring容器 - 编写Controller注入调用,验证Bean成功注册
验收标准:
- 访问接口,控制台打印
printInfo的内容
作业4:多环境配置练习
题目:
- 创建三套环境配置:dev(端口8080)、test(端口8081)、prod(端口80)
- 每套环境配置不同的数据库连接url
- 修改
spring.profiles.active切换环境,观察启动端口和配置变化 - 项目打成JAR包,用命令行参数切换到prod环境,验证端口变为80
验收标准:
- 切换环境,启动端口对应变化
- 命令行启动JAR包,prod环境生效
作业5:@Profile环境切换练习
题目:
- 定义
FileUploadService接口 - 编写dev环境实现:模拟本地上传,打印日志
- 编写prod环境实现:模拟OSS云存储上传,打印日志
- 切换环境,验证注入的实现类自动切换
验收标准:
- dev环境访问接口,返回“本地上传”
- prod环境访问接口,返回“OSS上传”
二、进阶选做题(学有余力完成)
选做1:外置配置文件验证
- 将项目打成JAR包
- 在JAR同级创建config目录,放入外部
application.yml - 修改外部配置端口为9090
- 启动JAR包,验证外部配置优先级更高
选做2:环境变量引用配置
- 数据库密码使用系统环境变量
${DB_PASSWORD}读取 - 在IDEA启动配置里设置环境变量
- 启动项目验证能正常读取
选做3:配置绑定松散绑定验证
- 配置文件用短横线写法
user.nick-name - Java字段用驼峰
nickName - 验证能正确读取
三、思考题(面试/笔试)
@Value和@ConfigurationProperties有什么区别?分别适用于什么场景?- Spring Boot配置优先级从高到低有哪些?配置不生效的排查思路是什么?
- Profile多环境有哪几种切换方式?优先级是怎样的?企业最佳实践是什么?
- YAML语法有哪些新手常见坑?
- 为什么生产环境的敏感信息不能提交到Git?列举两种处理方案。
- Spring Boot推荐XML配置还是Java配置类?为什么?
2.8 本章小结
- 配置文件:properties和YAML两种格式,YAML结构清晰是主流,重点注意缩进和空格语法坑
- 读取配置:
@Value适合单个配置;Environment适合动态读取;@ConfigurationProperties批量绑定+校验,企业首选 - 自定义配置:
@PropertySource加载properties;@ImportResource兼容XML;@Configuration+@BeanJava配置是推荐方式 - 多环境配置:多文件多Profile是企业主流;
@Profile控制Bean级环境;命令行参数激活优先级最高 - 企业实践:外置配置文件、配置优先级、敏感信息安全规范
- 排错能力:能独立排查配置不生效、读取失败等常见问题
下一章:Spring Boot Web开发进阶:拦截器、全局异常、文件上传、参数校验、跨域处理。