相关链接:
classpath 和 jar:https://www.theboyaply.cn/archives/classpath-and-jar
格式说明
Java 命令的通用格式在官方文档中定义得非常清楚:
java [options] -jar jarfile [args...]
[options]:这个位置是留给 JVM 本身使用的参数。-D(设置系统属性)和-javaagent(加载 Java 代理)都属于这个范畴,因此必须放在这里。-jar jarfile:这是固定写法,用于指定要运行的 JAR 包。[args...]:这个位置是留给传递给应用程序main方法的参数。如果你把-D或-javaagent放到这里,它们不会被当作 JVM 参数解析,而是会被错误地当作普通的应用程序参数传递给main方法,从而导致设置失效或程序行为异常。
两个区域,两种身份
- JVM参数区 (
-jar之前):这个区域是给Java虚拟机(JVM) 自己看的。像-D(设置系统属性)、-Xmx(设置堆内存)、-javaagent都属于这里。在代码中,你可以通过System.getProperty("key")来获取它们 。 - 应用程序参数区 (
-jar之后):这个区域是给你的应用程序看的。所有写在这里的内容,都会被当作普通的字符串,传递给你代码中main方法的String[] args参数。
解析流程图

Spring Boot的特殊处理
Spring Boot 在启动时,会主动去读取 main 方法接收到的 args 参数列表,并对它进行特殊解析。
- 识别标志:Spring Boot 规定,所有以双横杠
--开头的参数(例如--server.port=8081、--spring.profiles.active=prod),都会被它识别为配置属性。 - 注入环境:这些属性会被解析并加载到 Spring 的
Environment环境中。之后,你在代码中通过@Value("${server.port}")或Environment.getProperty()获取到的值,就来源于此 。 - 普通参数:如果你在
-jar后面放了不带--的参数,比如java -jar app.jar abc def,那么abc和def就只是args数组里的普通字符串,Spring Boot 不会把它们当作配置属性,但你可以通过实现CommandLineRunner接口等方式手动获取它们。
优先级:命令行的力量
这种设计让命令行参数拥有了非常高的优先级。在 Spring Boot 的配置体系中,命令行参数(-- 形式)的优先级是最高的 。
这意味着:
- 如果你的
application.yml里配置了server.port=8080。 - 同时你在启动命令中传入了
--server.port=8081。 - 那么最终生效的端口号将是 8081。命令行参数会覆盖掉配置文件里的值。
演示代码
首先,创建一个简单的Spring Boot应用,在启动时打印出接收到的所有args参数:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.ConfigurableEnvironment;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.out.println("===== main方法接收到的args参数 =====");
for (int i = 0; i < args.length; i++) {
System.out.println("args[" + i + "] = \"" + args[i] + "\"");
}
// 启动Spring Boot
ConfigurableEnvironment env = SpringApplication.run(DemoApplication.class, args)
.getEnvironment();
// 查看Spring Boot环境中的配置
System.out.println("\n===== Spring Boot Environment =====");
System.out.println("server.port = " + env.getProperty("server.port"));
System.out.println("==================================");
}
}
启动命令
使用你指定的命令启动:
java -jar demo.jar --server.port=8081 abc def
输出结果
运行后,控制台会输出:
===== main方法接收到的args参数 =====
args[0] = "--server.port=8081"
args[1] = "abc"
args[2] = "def"
===== Spring Boot Environment =====
server.port = 8081 # 成功从args[0]解析出来
==================================
end