前言
《【源码解析】凭什么?spring boot 一个 jar 就能开发 web 项目》 中有读者反应:
部署后运维很不方便,比较修改一个 IP 配置,需要重新打包。
这一点我是深有体会,17 年自学,并很大胆的直接在生产环境用的时候,我都是让产品经理(此时他充当我们的运维,嘿嘿)用压缩软件打开 jar,然后复制出配置,修改完之后再替换回去。为什么我这么大胆,因为当时才入行一年,而且觉得有架构师兜底,我就奔放了。你是不知道,当时负责这个项目的开发(c#开发)一开始不想用 SpringBoot 的。
不过如今看到这个问题,我有点震惊,都 9102 年了,竟然还担心这样的问题。我想说,哥们,这真的不是事儿。SpringBoot 早就提供了方法来解决这个问题。
SpringBoot 生产特性
SpringBoot 有很多生产特性,可以在生产环境中使用时更加方便。其中外部化配置基本都会用到。
Spring Boot 允许外部化配置,以便相同的应用在不同的环境中工作。
属性值可以在 Spring 环境中使用 @Value 或 @ConfigurationProperties 使用。
此次参考的版本是 SpringBoot-2.2.0.RELEASE
优先级
外部化配置的优先级顺序如下:
- Devtools 全局配置:当 devtools 启用时,
$HOME/.config/spring-boot
- 测试类中的
@TestPropertySource
- 测试中的
properties
属性:在 @SpringBootTest 和 用来测试特定片段的测试注解 - 命令行参数
SPRING_APPLICATION_JSON
中的属性:内嵌在环境变量或系统属性中的 JSONServletConfig
初始化参数ServletContext
初始化参数java:comp/env
中的 JNDI 属性- Java 系统属性:
System.getProperties()
- 操作系统环境变量
- 随机值(
RandomValuePropertySource
):random.*
属性 - jar 包外的指定 profile 配置文件:
application-{profile}.properties
- jar 包内的指定 profile 配置文件:
application-{profile}.properties
- jar 包外的默认配置文件:
application.properties
- jar 包内的默认配置文件:
application.properties
- 代码内的
@PropertySource
注解:用于@Configuration
类上 - 默认属性:通过设置
SpringApplication.setDefaultProperties
指定
注意:以上用 properties
文件的地方也可用 yml
文件
配置随机值
my.uuid=${random.uuid}
命令行属性
java -jar -Ddemo=vm demo.jar --demo=arg
- -Dxxx 为 vm 参数,在代码中通过
System#getProperty
获取 - --xxx 为 spring 命令行参数,通过
Environment#getProperty
获取,若通过此方法获取不到,会获取 vm 同名参数 - xxx.jar 之后的参数都是 arg 参数,都会在 main 方法中的 arg 数组中获取到
示例
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(ArgApplication.class, args);
LOGGER.info("----------------");
/* 打印 arg 参数 */
Arrays.stream(args)
.forEach(
arg -> {
LOGGER.info("arg:{}", arg);
});
/* 命令行传参 demo */
LOGGER.info("System#getProperty:{}", System.getProperty("demo"));
LOGGER.info("Environment#getProperty:{}", context.getEnvironment().getProperty("demo"));
}
输入命令
java -jar -Ddemo=vm arg-0.0.1-SNAPSHOT.jar aaa bbb ccc --demo=arg
效果如下:
----------------
arg:aaa
arg:bbb
arg:ccc
arg:--demo=arg
System#getProperty:vm
Environment#getProperty:arg
而如果执行命令是:
java -jar -Ddemo=vm arg-0.0.1-SNAPSHOT.jar aaa bbb ccc
结果如下:
arg:aaa
arg:bbb
arg:ccc
System#getProperty:vm
Environment#getProperty:vm
如果执行命令是:
java -jar arg-0.0.1-SNAPSHOT.jar aaa bbb ccc --demo=arg
结果如下:
arg:aaa
arg:bbb
arg:ccc
arg:--demo=arg
System#getProperty:null
Environment#getProperty:arg
属性文件
优先级:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
如果定义了 spring.config.location
,如:classpath:/custom-config/,file:./customr-config/