项目代码
项目结构图:

pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
</parent>
<packaging>jar</packaging>
<groupId>com.kaven</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot</name>
<description>springboot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>hello-world</finalName>
</build>
</project>
打包成JAR:
<packaging>jar</packaging>
application.properties:
server.port=8080
Spring Boot应用的默认启动端口也是8080,这里只是为了演示。
HelloWorldController:
package com.kaven.springboot.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloWorldController {
@GetMapping("/hello-world")
public String helloWorld() {
return "Hello World";
}
}
启动类:
package com.kaven.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
使用Maven打包Spring Boot项目,直接使用IDEA的快捷键。

双击即可打包Spring Boot项目,如下图所示,生成了hello-world.jar文件。

该文件的名称由pom.xml的如下配置指定:
<build>
<finalName>hello-world</finalName>
</build>
命令行属性
默认情况下,SpringApplication会将命令行属性(以--开头的参数,例如--server.port=9000)转换为property,并将它们添加到Spring Environment。命令行属性始终优先于基于配置文件的属性(配置源的优先级关系以后会介绍)。如果不想将命令行属性添加到Spring Environment中,可以通过SpringApplication.setAddCommandLineProperties(false)来禁用它们。
E:\workspace\IDEA\my\springboot> java -jar .\target\hello-world.jar --server.port=9999

很显然命令行属性覆盖了application.properties配置文件中关于应用启动端口的配置属性。
修改启动类:
package com.kaven.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringbootApplication.class);
application.setAddCommandLineProperties(false);
application.run(args);
// SpringApplication.run(SpringbootApplication.class, args);
}
}
SpringApplication application = new SpringApplication(SpringbootApplication.class);
application.run(args);
等价于:
SpringApplication.run(SpringbootApplication.class, args);
并且设置命令行属性不添加到应用程序上下文,即禁用它们。
application.setAddCommandLineProperties(false);
重新打包项目(需要先停止之前启动的JAR),再以如下所示的方式启动应用:
E:\workspace\IDEA\my\springboot> java -jar .\target\hello-world.jar --server.port=9999

现在命令行属性就不起作用了。
JSON属性
环境变量和系统属性通常有限制,这意味着某些属性名称不能使用。为了解决这个问题,Spring Boot允许将属性块编码为单个JSON结构。当应用程序启动时,任何spring.application.json或SPRING_APPLICATION_JSON属性都将被解析并添加到Spring Environment中。
SPRING_APPLICATION_JSON可以在UN*X shell的命令行中将属性作为环境变量提供(在Windows的CMD中运行会报错):
SPRING_APPLICATION_JSON='{"server":{"port":"9999"}}' java -jar target/hello-world.jar
JSON也可以作为系统属性提供:
java -Dspring.application.json='{"server":{"port":"9999"}}' -jar target/hello-world.jar
或者可以使用命令行属性提供JSON:
java -jar target/hello-world.jar --spring.application.json='{"server":{"port":"9999"}}'
虽然JSON中的null值将添加到结果属性源中,但PropertySourcesPropertyResolver会将null值视为缺失值,这意味着JSON不能用null值覆盖低优先级属性源中的属性。
到这里就结束了,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。
