说说 Spring Boot 的条件化配置 profile
因为部署环境的不同,应用所使用的配置参数也可能不同。比如开发环境与生产环境之间的配置参数就存在很大的区别。比如开发环境可能使用 H2 数据库,而在生产环境用的是 Oracle 数据库。
虽然在生产环境可以使用环境变量来配置参数,但如果参数太多,就不怎么方便。
更好的方式是使用 Spring profile,它是一种条件化配置机制, Spring Boot 启动时,会根据处于激活状态 profile 来加载相应的配置参数。
profile /ˈproʊfaɪl/
A representation of an object or a structure seen from the side.
1 定义 profile
定义的 profile 文件需要遵守以下规则:
- application-{profileName}.yml
- application-{profileName}.properties
假设有开发与生产环境,开发环境需要关闭 thymeleaf 的缓存,而生产环境需要开启 thymeleaf 的缓存。
创建一个名为 application-production.yml,内容如下:
spring:
# 开启缓存
thymeleaf:
cache: true
如果不想新建,也可以直接写在原 application.yml 中:
...
---
spring:
profiles: production
thymeleaf:
cache: true
原 application.yml 内容与 profile 之间使用3个中划线进行分割,然后使用 spring.profiles 属性来命名 profile。
2 激活指定 profile
(1)application.yml
可以在 application.yml 中指定需要激活的 profile 名称:
spring:
# 激活
profiles:
active:
- production
这种方式不够灵活,因为每次都需要修改配置文件。
(2)环境变量
在生产环境中更合适的方式是通过环境变量来设置需要激活的profile。形如:
export SPRING_PROFILES_ACTIVE= production
Linux 的export 命令可用于设置环境变量。
(3)命令行参数
如果是以可执行 JAR 文件的形式来启动应用, 就可以按照命令行参数的形式来指定需要激活的profile。形如:java -jar xxx.jar –spring.profiles.active=production
。
如果有多个需要激活的 profile,那么在环境变量中以逗号来分隔多个 profile,形如:export SPRING_PROFILES_ACTIVE= production1, production2
。
在 yml 中,需要以列表语法来设置多个需要激活的 profile,形如:
spring:
# 激活
profiles:
active:
- production1
- production2
3 控制 Bean 类或类中方法
可以在 profile 中指定需要创建Bean或者某些方法,用于这个 profile 下的特定场景。这时就会用到 @Profile 注解。
假设在应用的 xxxApplication中有一个初始化测试环境的方法,我们需要让这个方法只在 profile 为 test 时才执行,那么可以这样配置:
@Bean
@Profile("test")
public void initTestEnvironment(){
……
}
如果需要适配多个 profile,那么可以把 @Profile 的入参设定为数组,形如:@Profile({"test","development"})
;
如果只有某个 profile 不适用,比如总共定义了三个 profile,它们分别适用于开发、测试与生产环境。某个方法只在生产环境不需要执行,那么我们可以使用否定语法,形如:@Profile("! production")
当然也可以在类上应用 @Profile 注解,语法与作用与应用在 Bean 方法上相同。