上一篇 Spring Boot 之 Configuration 了解了自动配置的基本原理。默认配置可以满足很多场景,但实际项目中还是会修改端口、数据源等配置,而且开发、测试和生产环境的配置通常也不一样。
Spring Boot 支持命令行参数、Java 系统属性、环境变量、JNDI 和配置文件等多种外置配置方式。先用修改 Tomcat 监听端口做个简单测试。
启动项目时增加命令行参数:
java -jar target/spring-boot-hello-1.0-SNAPSHOT.jar --server.port=8081启动日志中可以看到端口已经变成 8081:
Tomcat started on port(s): 8081 (http)最常用的方式还是配置文件。在 src/main/resources 下创建 application.yml:
server:
port: 9090如果仍然带着前面的 --server.port=8081 启动,监听端口还是 8081。删除命令行参数后再次启动,端口才会变成 9090。这是因为命令行参数的优先级高于配置文件。
配置优先级
同一个配置项出现在多个位置时,优先级高的值会覆盖优先级低的值。Spring Boot 1.5.4 中,主要顺序由高到低如下:
- Devtools 用户目录下的全局配置
- 测试中的
@TestPropertySource @SpringBootTest的properties属性- 命令行参数
SPRING_APPLICATION_JSONServletConfig初始化参数ServletContext初始化参数java:comp/env中的 JNDI 属性- Java 系统属性
- 操作系统环境变量
random.*随机属性- Jar 包外部的
application-{profile}.properties或 YAML 文件 - Jar 包内部的
application-{profile}.properties或 YAML 文件 - Jar 包外部的
application.properties或 YAML 文件 - Jar 包内部的
application.properties或 YAML 文件 @Configuration类上的@PropertySourceSpringApplication.setDefaultProperties()指定的默认属性
平时开发主要会接触命令行参数、环境变量和配置文件。临时覆盖某个配置时可以使用命令行参数,固定配置则放在配置文件中。
application.properties 和 application.yml 默认可以放在以下四个位置,顺序同样由高到低:
- 应用运行目录下的
/config子目录 - 应用运行目录
- Classpath 下的
/config包 - Classpath 根目录
例如,运行目录的 config/application.yml 会覆盖 Jar 包内部 application.yml 中的同名配置。
使用 Profile
程序部署到不同环境时通常使用不同配置。例如开发环境关闭 Thymeleaf 缓存,测试环境和生产环境使用不同的数据源。
在一个 YAML 文件中,可以使用三个减号分隔不同环境的配置,再通过 spring.profiles 指定环境名称。下面的 server.port 没有指定 Profile,所以在所有环境中都会生效:
server:
port: 9090
---
spring:
profiles: development
thymeleaf:
cache: false
---
spring:
profiles: production
thymeleaf:
cache: true配置项较多时,把多个环境都放在一个文件里不太容易维护。也可以分别创建 application-development.yml 和 application-production.yml,文件名中的 development、production 就是 Profile 名称,文件内部不需要再声明 spring.profiles。
application-development.yml:
spring:
thymeleaf:
cache: falseapplication-production.yml:
spring:
thymeleaf:
cache: true除了配置文件,还可以直接在配置类上使用 @Profile:
@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}配置项通常放在 application-{profile}.yml 中更直观,@Profile 更适合控制某组 Bean 是否加载。
最后激活开发环境。在 application.yml 中增加:
spring:
profiles:
active: development也可以在启动时指定:
java -jar target/spring-boot-hello-1.0-SNAPSHOT.jar \
--spring.profiles.active=development在 IDEA 中启动项目,修改 Thymeleaf 模板后执行一次 Build Project(Ctrl + F9),开发环境关闭缓存时再次访问就能看到修改;切换到 production 后模板缓存开启,需要重启应用才能生效。
外置配置解决的是同一份程序在不同环境下使用不同参数的问题,Profile 则把一组相关配置组织起来。完整的优先级和 Profile 规则可以对照 Spring Boot 1.5.4 外置配置文档。