前言:在之前的开发环境中要跟改配置,测试环境也要改,每次切换环境都要手动修改配置文件
常常发生"我们在本地能运行,怎么部署到服务器就报错"的情况,一不小心就把测试环境的配置提交到代码库。因此我们提出了多环境开发配置。
多环境开发配置:
在SpringBoot中,多环境配置的管理核心是利用Profile机制,它允许我们为不同的运行环境(开发,测试,生产)定义独立的配置,并在应用启动时动态的激活,从而实现配置等隔离与灵活切换。
核心实现方式:Profile 特定配置文件
总之就是为每个环境创建独立的配置文件,根据实际需求进行修改。
| application.yml:公共配置文件,存放所有环境通用的配置 。 |
|---|
| application-dev.yml:开发环境(dev)的专属配置。 |
| application-test.yml:测试环境(test)的专属配置。 |
| application-prod.yml:生产环境(prod)的专属配置 |
事例:
公共配置,可以设置一个默认激活的Profile,比如开发环境
spring: profiles: active: dev application: name: my-spring-boot-app
其他公共配置...
开发环境特定配置
server: port: 8081
spring: datasource: url: jdbc:mysql://localhost:3306/dev_db?useSSL=false username: dev_user password: dev_password jpa: hibernate: ddl-auto: update show-sql: true
logging: level: root: DEBUG
配置文件的加载机制:
启动应用 → 读取spring.profiles.active → 加载匹配的环境配置文件
SpringBoot是如何根据环境来匹配对应的配置呢,底层核心机制是Spring Boot是通过 ConfigFileApplicationListener 和 PropertySourceLoader 来实现这个功能的。总之,Spring Boot通过文件名匹配 + 配置合并 + 优先级覆盖的机制,实现了环境与配置的自动对应。
// Spring Boot源码中的关键组件 public class ConfigFileApplicationListener {
// 配置文件加载器
private Set<String> getSearchLocations() {
Set<String> locations = new LinkedHashSet<>();
// 默认扫描位置:classpath:/, classpath:/config/, file:./, file:./config/
locations.add("classpath:/");
locations.add("file:./");
return locations;
}
// 构建要加载的文件名
private List<String> getFilenames(Profile profile) {
List<String> names = new ArrayList<>();
names.add("application"); // 基础文件名
if (profile != null) {
names.add("application-" + profile); // 环境特定文件名
}
return names;
}
}
设计思想:
| 特性 | 说明 |
|---|---|
| 约定优于配置 | Spring Boot通过命名规则自动发现配置,无需手动声明 |
| 覆盖机制 | 环境特定配置覆盖基础配置,优先级更高 |
| 继承关系 | 环境配置只定义差异项,减少重复 |
| 外部化配置 | 可以通过命令行/环境变量动态指定使用哪个环境 |
而当我们把项目的jar包打包给前端人员是,我们在主配置类中一般是默认一个环境,而当前端人员需要其他的环境时,还需要我们后端人员修改默认配置,然后再打包给前端吗,当然不用这么麻烦,这就是下面我们要学习的多环境命令行启动。
多环境命令行启动:
指定环境:
开发环境
java -jar tlias-web-management-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
测试环境
java -jar tlias-web-management-0.0.1-SNAPSHOT.jar --spring.profiles.active=test
生产环境
java -jar tlias-web-management-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
指定环境+接口:
开发环境,使用8081端口
java -jar myapp.jar --spring.profiles.active=dev --server.port=8081
生产环境,使用80端口
java -jar myapp.jar --spring.profiles.active=prod --server.port=80
指定环境+数据库连接:
临时覆盖数据库连接
java -jar myapp.jar --spring.profiles.active=dev
--spring.datasource.url=jdbc:mysql://localhost:3306/testdb
--spring.datasource.username=testuser
--spring.datasource.password=testpass
注意点:当执行maven生命周期的时候,先执行clean,之后再进行打包,同时要在设置中把字符集设置成UTF-8,防止乱码。
Spring Boot 配置优先级(从高到低)
- 命令行参数(最高)
- JVM 系统参数(-D参数)
- 环境变量
- 配置文件(application.yml)
- 默认值(最低)
原理:
Spring Boot多环境命令行参数的原理可以概括为:
- 解析阶段:Spring Boot通过
SimpleCommandLineArgsParser解析--key=value格式的参数 - 存储阶段:将解析后的参数封装成
CommandLinePropertySource,作为最高优先级的属性源 - 合并阶段:将所有属性源(命令行、环境变量、配置文件等)按优先级组成链表
- 读取阶段:
PropertyResolver按优先级顺序查找属性值,返回第一个找到的值 - 应用阶段:通过
@Value、@ConfigurationProperties等方式将属性注入到Bean中
这就是为什么命令行参数能够覆盖配置文件中的设置,并且能够动态指定环境的原因
Maven与SpringBoot多环境兼容问题:
首先我们先区分一下这两个多环境开发:
Maven多环境开发
形象的说,Maven的多环境开发就相当于是在建造不同的房子,不同的环境就是不同的建筑队,
好比是:
- 开发环境 → 请"快装公司"(快速施工,能随时改)
- 测试环境 → 请"标准公司"(按规范施工)
- 生产环境 → 请"精装公司"(精细施工,质量第一)
✅ 带不同的工具(依赖包)
✅ 用不同的材料(资源文件)
✅ 按不同的标准(插件配置)
✅ 干完活就走(构建完成就结束
这些打包之后是不同的jar包
SpringBoot的多环境开发:
是同一套房子的不同居住方式
- 开发模式 → 白天办公用(开大灯、开电脑、放工作音乐)
- 休闲模式 → 晚上休息用(开小夜灯、放轻音乐)
- 聚会模式 → 周末party用(开彩灯、放嗨曲、开空调)
- ✅ 开不同的灯(不同端口)
- ✅ 放不同的音乐(不同日志级别)
- ✅ 用不同的电器(不同数据源)
- ✅ 随时切换模式(运行时改参数
这些打包之后是同一个jar包。
这时我们就会有疑问,为什么这两个看似毫不相干的工作,会产生兼容问题呢。简单的说,当我们建造的是普通简单的房子时,而SpringBoot却要按照豪华型房子居住,未免有点强人所难。实际上的兼容问题就是配置的重复定义,资源过滤冲突,多环境组合混乱。
兼容的解决方案(多环境组合混乱):
mvn clean package -Pdev # Maven的dev java -jar app.jar --spring.profiles.active=test # Spring的test
结果:Maven用dev配置打包,Spring用test配置运行,完全不匹配
Maven中设置多环境属性
<profiles><profile>
<id>dev_env</id><properties>
<profile.active>dev</profile.active></properties><activation><activeByDefault>true</activeByDefault></activation></profile><profile>
<id>pro_env</id><properties><profile.active>pro</profile.active></properties>
</profile><profile>
<id>test_env</id><properties><profile.active>test</profile.active></properties>
</profile></profiles>
SpringBoot中引用Maven属性
spring:profiles: active: ${profile.active}占位符,解析占位符,加载Maven的属性 spring: profiles:proserver: port:80spring: profiles:devserver: port:81 spring:profiles: testserver: port:82
对资源文件开启对默认占位符的解析
<build><plugins><plugin>
<artifactId>maven-resources-plugin</artifactId><configuration>
<encoding>utf-8</encoding>
<useDefaultDelimiters>true</useDefaultDelimiters>
</configuration></plugin></plugins></build>
这里的资源插件的作用是把pom.xml文件中的值传到配置文件,而不是Spring的占位符需要资源插件,Spring占位符的解析是Spring框架自带的功能
| 方面 | maven-resources-plugin | Spring PropertyResolver |
|---|---|---|
| 所属 | Maven插件 | Spring框架核心 |
| 处理对象 | @...@ | ${...} |
| 处理时机 | 编译时 | 运行时 |
| 配置位置 | pom.xml | application.yml |
| 必须配置吗 | 不是必须的 | 自动集成,无需配置 |
| 依赖 | 需要显式声明 | Spring Boot自带 |
配置文件分类
SpringBoot中4级配置文件
1级: file : config/application.yml
【最高】
2级: file :application.yml
3级: classpath: config/application.yml
4级: classpath: application.yml
【最低】
作用:
1级与2级留做系统打包后设置通用属性
3级与4级用于系统开发阶段设置通用属性
结语:
最后的最后,感谢大家观看到最后,如果对你有帮助,请**一键三连,点赞,关注(拜托了),收藏,**你的支持就是我最大的鼓励,持续更新对你有帮助的知识!

《SpringBoot多环境配置实战指南》 是转载文章,点击查看原文。