首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SpringBoot多环境配置实战指南

SpringBoot多环境配置实战指南

作者头像
北极的代码
发布2026-04-22 18:29:14
发布2026-04-22 18:29:14
1020
举报

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

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

多环境开发配置:

在SpringBoot中,多环境配置的管理核心是利用Profile机制,它允许我们为不同的运行环境(开发,测试,生产)定义独立的配置,并在应用启动时动态的激活,从而实现配置等隔离与灵活切换。

核心实现方式:Profile 特定配置文件

总之就是为每个环境创建独立的配置文件,根据实际需求进行修改。

application.yml:公共配置文件,存放所有环境通用的配置 。

application-dev.yml:开发环境(dev)的专属配置。

application-test.yml:测试环境(test)的专属配置。

application-prod.yml:生产环境(prod)的专属配置

事例:
代码语言:javascript
复制
# 公共配置,可以设置一个默认激活的Profile,比如开发环境
spring:
  profiles:
    active: dev 
  application:
    name: my-spring-boot-app
# 其他公共配置...
代码语言:javascript
复制
# 开发环境特定配置
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通过文件名匹配 + 配置合并 + 优先级覆盖的机制,实现了环境与配置的自动对应。

代码语言:javascript
复制
// 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包打包给前端人员是,我们在主配置类中一般是默认一个环境,而当前端人员需要其他的环境时,还需要我们后端人员修改默认配置,然后再打包给前端吗,当然不用这么麻烦,这就是下面我们要学习的多环境命令行启动。

多环境命令行启动:

指定环境:
代码语言:javascript
复制
# 开发环境
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
指定环境+接口:
代码语言:javascript
复制
# 开发环境,使用8081端口
java -jar myapp.jar --spring.profiles.active=dev --server.port=8081

# 生产环境,使用80端口
java -jar myapp.jar --spring.profiles.active=prod --server.port=80
指定环境+数据库连接:
代码语言:javascript
复制
# 临时覆盖数据库连接
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的多环境开发就相当于是在建造不同的房子,不同的环境就是不同的建筑队,

代码语言:javascript
复制
# 好比是:
- 开发环境 → 请"快装公司"(快速施工,能随时改)
- 测试环境 → 请"标准公司"(按规范施工)
- 生产环境 → 请"精装公司"(精细施工,质量第一)

✅ 带不同的工具(依赖包)

✅ 用不同的材料(资源文件)

✅ 按不同的标准(插件配置)

✅ 干完活就走(构建完成就结束

这些打包之后是不同的jar包

SpringBoot的多环境开发:

是同一套房子的不同居住方式

代码语言:javascript
复制
- 开发模式 → 白天办公用(开大灯、开电脑、放工作音乐)
- 休闲模式 → 晚上休息用(开小夜灯、放轻音乐)
- 聚会模式 → 周末party用(开彩灯、放嗨曲、开空调)
  • ✅ 开不同的灯(不同端口)
  • ✅ 放不同的音乐(不同日志级别)
  • ✅ 用不同的电器(不同数据源)
  • ✅ 随时切换模式(运行时改参数

这些打包之后是同一个jar包。

这时我们就会有疑问,为什么这两个看似毫不相干的工作,会产生兼容问题呢。简单的说,当我们建造的是普通简单的房子时,而SpringBoot却要按照豪华型房子居住,未免有点强人所难。实际上的兼容问题就是配置的重复定义,资源过滤冲突,多环境组合混乱。

兼容的解决方案(多环境组合混乱):

代码语言:javascript
复制
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级用于系统开发阶段设置通用属性

结语:

最后的最后,感谢大家观看到最后,如果对你有帮助,请一键三连,点赞,关注(拜托了),收藏,你的支持就是我最大的鼓励,持续更新对你有帮助的知识!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多环境开发配置:
    • 核心实现方式:Profile 特定配置文件
      • 事例:
    • 配置文件的加载机制:
    • 设计思想:
  • 多环境命令行启动:
    • 指定环境:
    • 指定环境+接口:
    • 指定环境+数据库连接:
  • Spring Boot 配置优先级(从高到低)
    • 原理:
  • Maven与SpringBoot多环境兼容问题:
    • Maven多环境开发
    • SpringBoot的多环境开发:
  • 兼容的解决方案(多环境组合混乱):
  • 配置文件分类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档