Java启动时通过-Dspring.profiles.active=dev等JVM参数指定环境配置文件,配合application-{profile}.yml加载对应配置,且-D参数须置于-jar之前。

Java启动时怎么指定不同环境的配置文件
Java应用本身不识别“dev/test/prod”这类环境标签,它只认具体的java命令参数。所谓“不同环境配置”,本质是让JVM在启动时加载不同的配置路径或覆盖特定属性值。
最直接有效的方式是用-D传系统属性,再配合配置加载逻辑(比如Spring Boot的spring.profiles.active)生效:
-
java -Dspring.profiles.active=dev -jar app.jar→ 激活application-dev.yml -
java -Dspring.profiles.active=test -Dserver.port=8081 -jar app.jar→ 同时覆盖profile和端口 - 非Spring项目也可用
-Dconfig.path=/etc/myapp/prod.conf,然后代码里读System.getProperty("config.path")
注意:-D参数必须放在-jar之前,否则会被当成jar参数忽略;多个-D可并列,顺序无关。
OpenJDK 17+ 的模块化配置怎么按环境隔离
从JDK 9起引入模块系统,但模块路径(--module-path)本身不支持“环境分支”。真正需要按环境区分的是模块内容——比如你有com.example.logging.dev和com.example.logging.prod两个模块。
做法是:用--module显式声明主模块,并通过--add-modules动态加入对应环境模块:
- 开发环境:
java --module-path mods --module myapp/com.example.Main --add-modules com.example.logging.dev - 生产环境:
java --module-path mods --module myapp/com.example.Main --add-modules com.example.logging.prod
关键点:模块名必须唯一,不能靠路径区分;--add-modules必须写全限定模块名,不能用通配符。
Windows/Linux下切换环境配置的脚本怎么写才不踩坑
手动改JAVA_HOME再重开终端太慢,用脚本自动化时容易犯两个错:变量没导出、PATH没刷新、旧进程残留。
推荐方案是封装为独立启动脚本,不依赖全局JAVA_HOME:
- Linux/macOS(
start-prod.sh):#!/bin/bash export JAVA_HOME="/opt/java/jdk-17" export PATH="$JAVA_HOME/bin:$PATH" exec java -Dspring.profiles.active=prod -jar /opt/app/app.jar
- Windows(
start-dev.bat):@echo off set JAVA_HOME=D:\Java\jdk-8 set PATH=%JAVA_HOME%\bin;%PATH% java -Dspring.profiles.active=dev -jar app.jar
重点:用exec(Linux)或直接java(Windows)启动,避免子shell退出后变量失效;不要用setx或set JAVA_HOME=去改系统级变量,那是给其他程序用的,不是给当前命令用的。
为什么JAVA_HOME设对了,java -version还是显示旧版本
因为PATH里存在更早注册的java.exe路径,系统优先找到了它。常见来源有:
- Oracle安装器自动加的
C:\Program Files (x86)\Common Files\Oracle\Java\javapath - 旧版JDK残留的
PATH条目(如C:\Program Files\Java\jdk1.8.0_202\bin) - IDE(如IntelliJ)在后台启动的
java进程缓存了旧路径
验证方法:在CMD/PowerShell里运行where java(Windows)或which java(Linux/macOS),看输出的第一行是不是你期望的%JAVA_HOME%\bin\java.exe。如果不是,删掉PATH里排在前面的干扰路径,或者把%JAVA_HOME%\bin移到PATH最开头。
多版本共存时,JAVA_HOME只是个“指向标”,真正起效的是PATH里哪个java先被找到——这点比任何文档都重要,也最容易被忽略。











