说说 Spring Boot 的条件化配置 profile

79 阅读2分钟

因为部署环境的不同,应用所使用的配置参数也可能不同。比如开发环境与生产环境之间的配置参数就存在很大的区别。比如开发环境可能使用 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 文件需要遵守以下规则:

  1. application-{profileName}.yml
  2. 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 方法上相同。