SpringBoot多环境配置实战指南

作者:北极的代码日期:2026/2/22

前言:在之前的开发环境中要跟改配置,测试环境也要改,每次切换环境都要手动修改配置文件

常常发生"我们在本地能运行,怎么部署到服务器就报错"的情况,一不小心就把测试环境的配置提交到代码库。因此我们提出了多环境开发配置。

多环境开发配置:

在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是通过 ConfigFileApplicationListenerPropertySourceLoader 来实现这个功能的。总之,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 配置优先级(从高到低)

  1. 命令行参数(最高)
  2. JVM 系统参数(-D参数)
  3. 环境变量
  4. 配置文件(application.yml)
  5. 默认值(最低)

原理:

Spring Boot多环境命令行参数的原理可以概括为:

  1. 解析阶段:Spring Boot通过SimpleCommandLineArgsParser解析--key=value格式的参数
  2. 存储阶段:将解析后的参数封装成CommandLinePropertySource,作为最高优先级的属性源
  3. 合并阶段:将所有属性源(命令行、环境变量、配置文件等)按优先级组成链表
  4. 读取阶段PropertyResolver按优先级顺序查找属性值,返回第一个找到的值
  5. 应用阶段:通过@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-pluginSpring PropertyResolver
所属Maven插件Spring框架核心
处理对象@...@${...}
处理时机编译时运行时
配置位置pom.xmlapplication.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多环境配置实战指南》 是转载文章,点击查看原文


相关推荐


聊一聊 CLI:为什么真正的工程能力,都藏在命令行里?
G探险者2026/2/14

大家好,我是G探险者! 今天我们来聊一聊CLI。 在很多人眼里,命令行(CLI,Command Line Interface)是“黑框 + 英文命令”的代名词。 对普通用户来说,它晦涩、难记、不友好。 但对工程师来说—— CLI 是系统可编排能力的起点,是自动化的基础设施,是 DevOps 的地基。 今天我们不从“怎么用命令”讲起,而是聊一聊: CLI 是怎么诞生的? 为什么它没有被 GUI 取代? 为什么所有现代基础设施几乎都优先设计 CLI? 为什么 CLI 是工程能力的分水岭?


你这一生到底该如何赚钱?
袁庭新2026/2/5

大家好,我是袁庭新。 赚钱是每个成年人每天的头等大事,那你有没有认真思考过:你这一辈子到底应该如何赚钱?根据这几年的总结,我认为赚钱的方式无非以下三种: 用时间赚钱 用金钱赚钱 用金钱和时间一起赚钱 这三种赚钱方式的回报是不一样的,它们依次越来越大,最牛的就是用“时间+金钱”赚钱。 我们绝大多数人一生摆脱不了“用时间赚钱”这种模式,想要获得更多回报就低拼命上班加班。但,用时间赚钱的方式是可以改良的,最核心的策略就是“想尽一切办法把自己的同一份时间出售很多次”,举几个例子吧,比如:讲课、写书


爷爷你关注的前端博主复活了!! 他学python去了??
jinzunqinjiu2026/1/27

如何配置python环境。 hello,兄弟们马上过年了,想死你们了。转眼间就已经毕业半年。也工作了快一年了。从实习生一路跌跌撞撞,从刚开始连react的状态依赖都老是写死循环到现在已经经历过很多项目了。说来这一年也有很多成长,参与了公司很多的项目,看过各种代码。最终在ai的加持下已经能够独挡一面。但是最近公司开始掀起了一股ai风,以及网上ai全栈的兴起,我想我是坐不住了。深耕前端 or 技术转型。 小孩子才做选择,前端为主ai为辅,所以我要开始学习python逐渐开始学习ai应用了。正好我也没


【我与2025】裁员、旅游、找工作、媳妇没跑
修己xj2026/1/18

现在是2026年1月下旬。以往的年终总结总被搁置,今年却有些不同——家里添了新成员,自己的心态也悄然变化。于是决定写下这些文字,既是回顾我的2025,也是一次认真的复盘。 裁员 2021年6月,我加入上一家公司,一待就是四年。2025年收到的第一份“礼物”,竟是公司的裁员通知。我负责的是运营业务系统,因为常有线上问题需要处理,所以即便下班后、节假日也离不开电脑。几年来,我几乎没出省旅行过,每次回家都随身带着电脑,随时待命。 刚入职时,公司正处于扩张期,盈利状况很好。没过多久,就搬进了自购的整层


Incremark Solid 版本上线:Vue/React/Svelte/Solid 四大框架,统一体验
king王一帅2026/1/10

Incremark 现已支持 Solid,至此完成了对 Vue、React、Svelte、Solid 四大主流前端框架的全面覆盖。 为什么要做框架无关 市面上大多数 Markdown 渲染库都是针对特定框架开发的。这带来几个问题: 重复造轮子:每个框架社区都在独立实现相似的功能 能力不一致:不同框架的实现质量参差不齐 团队切换成本:换框架意味着重新学习新的 API Incremark 采用不同的思路:核心逻辑与 UI 框架完全解耦。 @incremark/core 负责所有解析、转换、增量更


机器学习数据集完全指南:从公开资源到Sklearn实战
郝学胜-神的一滴2026/1/1

机器学习数据集完全指南:从公开资源到Sklearn实战 1. 引言:为什么数据集如此重要?2. 机器学习公开数据集大全2.1 综合型数据集平台2.2 领域特定数据集 3. Sklearn内置数据集详解3.1 小型玩具数据集3.2 大型真实世界数据集3.3 完整列表 4. Sklearn数据集加载实战4.1 基本加载方法4.2 数据集对象结构4.3 转换为Pandas DataFrame 5. Sklearn数据集处理API大全5.1 数据分割5.2 特征缩放5.3 特征编码5.4


Gradle 基础篇之基础知识的介绍和使用
一线大码2025/12/23

1. 项目结构 目录介绍: build.gradle:项目编译时要读取的配置文件,build.gradle有两个,一个是全局的,一个是在模块里面。全局的build.gradle主要设置的是声明仓库源,gradle的版本号说明等。 gradlew:linux下的gradle环境脚本。可以执行gradle指令,比如./greadle build。 gradlew.bat:windows下的gradle环境脚本。可以执行gradle指令。 settings.gradle:包含一些必要设置,例如,任


人工智能入门概念介绍
Shawn_Shawn2025/12/15

最近公司正在推荐Ai相关项目,目前主要是大模型相关的应用层面开发,但自己还是希望能够基础入手,全方位了解一下机器学习,深度学习,强化学习,自然语言,大模型等Ai相关的知识点,仅了解相关概念,不去深入了解算法实现。本文主要介绍一下机器学习的基本概念。 什么是机器学习 引用周志华带佬的机器学习一书提到的案例,我们在生活中挑选西瓜的时候,经常会假嘛若鬼地敲一下西瓜,听一听声音,如果发出 “嘭嘭” 的闷声,说明西瓜成熟度好,果肉饱满。若发出 “当当” 的清脆声,可能西瓜还未成熟;若发出 “噗噗” 声,则


无需修改测试用例实现Selenium四倍性能提升的完整方案
测试人社区—52722025/12/6

在测试自动化中,Selenium的执行效率直接影响项目交付速度和资源成本。本文将针对无需修改测试用例的前提,从驱动配置、执行策略及环境优化三个维度,系统介绍提升Selenium执行速度400%的实战方案。 一、浏览器驱动层深度优化 1. 启用新一代无头模式(Headless Mode) # Chrome无头模式配置示例 options = webdriver.ChromeOptions() options.add_argument('--headless=new') options.add


JWT教程
y1y1z2025/11/28

JWT技术 描述:JWT是用于根据特征值生成Token(凭证)的工具库,常用于身份校验功能 JWT特性 JWT天然携带信息,可以快速实现“多设备登录” 管理、登出、重复登录检验等功能JWT支持签名加密,开发者也可以初步校验特征值,保证了一定的安全性 token = Header + Payload + Signature Header:签名算法 + token类型(固定为JWT),例如{ "alg": "HS256","type": "JWT"}Signature:密文最后拼接密钥

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客