
前言:在之前的开发环境中要跟改配置,测试环境也要改,每次切换环境都要手动修改配置文件
常常发生"我们在本地能运行,怎么部署到服务器就报错"的情况,一不小心就把测试环境的配置提交到代码库。因此我们提出了多环境开发配置。
在SpringBoot中,多环境配置的管理核心是利用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多环境命令行参数的原理可以概括为:
SimpleCommandLineArgsParser解析--key=value格式的参数
CommandLinePropertySource,作为最高优先级的属性源
PropertyResolver按优先级顺序查找属性值,返回第一个找到的值
@Value、@ConfigurationProperties等方式将属性注入到Bean中
这就是为什么命令行参数能够覆盖配置文件中的设置,并且能够动态指定环境的原因
首先我们先区分一下这两个多环境开发:
形象的说,Maven的多环境开发就相当于是在建造不同的房子,不同的环境就是不同的建筑队,
# 好比是:
- 开发环境 → 请"快装公司"(快速施工,能随时改)
- 测试环境 → 请"标准公司"(按规范施工)
- 生产环境 → 请"精装公司"(精细施工,质量第一)✅ 带不同的工具(依赖包)
✅ 用不同的材料(资源文件)
✅ 按不同的标准(插件配置)
✅ 干完活就走(构建完成就结束
这些打包之后是不同的jar包
是同一套房子的不同居住方式
- 开发模式 → 白天办公用(开大灯、开电脑、放工作音乐)
- 休闲模式 → 晚上休息用(开小夜灯、放轻音乐)
- 聚会模式 → 周末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级用于系统开发阶段设置通用属性
结语:
最后的最后,感谢大家观看到最后,如果对你有帮助,请一键三连,点赞,关注(拜托了),收藏,你的支持就是我最大的鼓励,持续更新对你有帮助的知识!
