由于Spring Boot 2.4系列的配置变动了,导致了配置的修改方式也有所改变
简要表示。
利用Spring Boot的配置文件功能spring.profiles.include,可以吸收不同环境中(例如,测试和生产环境的AWS S3存储桶)的差异。在应用程序启动时,通过将spring.profiles.active指定为JVM选项,可以实现环境差异的吸收。
逗号分隔的活动配置文件列表。可通过命令行开关进行覆盖。
因为升级到Spring Boot 2.4.X版本后,之前的行为发生了变化,所以需要进行相应的更改。在这里,我将记下修改的方法。
参考链接
使用spring.profiles.include和活动配置文件来更改spring-profiles的顺序
将spring.profiles.include迁移到spring.profiles.group
移除spring.profiles的支持
提供详细信息
我以以下方式创建了一个名为application.yml的文件,并设置了文件名。
└── src
├── main
│ └── resources
│ ├── application-development.yml
│ ├── application-development-include1.yml
│ ├── application-development-include2.yml
│ ├── application.yml
└── test
└── resources
├── application-test-include.yml
├── application-test.yml
每个文件都包含了一个单独的配置文件,这样可以吸收环境差异。
-Dspring.profiles.active=development
当指定时,使得能够获取与开发相关的所有属性。
以下是application.yml的内容的大致概念。(您无需使用“:”和换行,只使用“.”作为键也可以正常工作。
发展档案
spring.profiles.include:
- development-include1
- development-include2
spring:
datasource:
username: root
duplicate.key: "I'm a development"
include1.development: include1。developmentプロファイルにより参照(ymlなのでUTF-8エンコードできています)
include2.development: include2。developmentプロファイルにより参照(ymlなのでUTF-8エンコードできています)
考试个人资料
spring.profiles.include: test-include
spring:
datasource:
username: sa
duplicate.key: "I'm a test"
include.test: this_is_test_key
在Spring Boot 2.3.x版本之前,只需正确指定配置文件即可使以下功能正常运行。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment
@Configuration
class MyConfiguration {
@Bean
fun check(env: Environment): List<String?> {
val development1 = env.getProperty("include1.development")
val development2 = env.getProperty("include2.development")
val test = env.getProperty("include.test")
val profileNameFileKey = env.getProperty("duplicate.key")
if (env.activeProfiles.any { it == "development" }) {
require(development1 == "include1。developmentプロファイルにより参照(ymlなのでUTF-8エンコードできています)") { "間接的なインクルードができていません" }
require(development2 == "include2。developmentプロファイルにより参照(ymlなのでUTF-8エンコードできています)") { "間接的なインクルードができていません" }
require(profileNameFileKey == "I'm a development") { "プロファイルと同じ名前のファイル名を読み込めていません。" }
require(test.isNullOrEmpty()) { "development の時に test が読み込まれています。" }
} else {
require(development1.isNullOrEmpty()) { "test の時に、development が読み込まれています。" }
require(development2.isNullOrEmpty()) { "test の時に、development が読み込まれています。" }
require(test == "this_is_test_key") { "間接的にテストのキーをインクルードできていません。" }
require(profileNameFileKey == "I'm a test") { "プロファイルと同じ名前のファイルが読み込まれていません。" }
}
return listOf(development1, development2, test, profileNameFileKey)
}
}
升级到Spring Boot 2.4.X后,不再包含通过spring.profiles.include指定的配置文件,因此无法获取已包含的配置文件键。
原因是一个我们选择这么做的因素。
看起来,从Spring Boot 2.4.x开始,似乎无法使用application-{profile-name}.yml 文件中的 spring.profiles.include 属性将另一个配置文件与当前配置文件相关联了。在application.yml中描述包含的配置文件,可以读取所有配置文件的键和值。
spring.profiles.include:
- development-include1
- development-include2
- test-include
然而,由于这种方法会加载所有的文件,所以无法根据配置文件的不同来包含不同的文件,以应对环境差异。
原因和变更方法
根据官方文档所述,由于ConfigFileApplicationListener变得复杂而需要进行更改。对于本次案例,官方提出它作为问题点。
・你可以从特定个人资料文档中启用额外的配置文件。
・很难知道文档的添加顺序。
似乎符合其中一项。
作为应对措施,我们将执行官方文件中所述的内容。
将个人资料分组
根据 spring.profiles.group 的说明,可以对配置文件进行分组。因此,针对开发和测试配置文件,需要关联其他必要的配置文件并创建分组。
根据上述,配置文件似乎只能在 application.yml 中定义,所以将分组信息写入 application.yml 文件中。
spring.profiles.group:
development:
- development-include1
- development-include2
test:
- test-include
包含了可以使用的文件密钥。文件中已经包含了在配置文件中写的密钥,所以没有问题。
使用多文档功能
听说Spring Boot的application.properties和application.yml现在实现了yml的多文档功能,可以将一个文件(application.properties或application.yml)在逻辑上分割成多个文档。然而,只是逻辑上分割并没有意义,所以为了使用多文档功能,从Spring Boot 2.4.x开始,实现了spring.config.activate.on-profile属性。
test=value
#---
test=overridden-value
上面的例子有点不切实际,因为始终覆盖一个值不太合理。更常见的设置是声明第二个文档只在特定配置文件下生效。
在Spring Boot 2.3中,您可以使用spring.profiles键来实现这一点。而在Spring Boot 2.4中,我们决定将属性更改为spring.config.activate.on-profile。
我试过使用多文档功能来测试spring.profiles.include,但它没有正常工作。虽然我在on-profile下指定了include,但无论在哪个配置文件下运行应用程序,都会读取所有配置文件。因为官方文档中没有提到spring.profiles.include,而是使用spring.config.import,所以我需要使用spring.config.import。不过,对于测试资源文件(如application-test.yml),当构建生产代码时,它们不会包含在构建路径中,所以当直接指定文件名时,会抛出文件找不到的异常。因此,我需要在这个页面中提到的optional字段。
spring.datasource.sql-script-encoding: UTF-8
---
spring:
config:
activate:
on-profile: development
import:
- optional:application-development-include1.yml # development で動かした時は問題ないが、test のプロファイルで動かすと見つからないというエラーになるので、optional にする。
- optional:application-development-include2.yml
---
spring:
config:
activate:
on-profile: test
import:
- optional:application-test-include.yml # test は、production のビルドに入らないので、optional にしないといけない
在这种方法中,我们可以加载 application-{profile}.yml 文件,而无需指定文件名即可读取键。
以下是中文的上述表达的同义句:
这是我对此的感受。
第二种方法的行为有些微妙,增加了一些复杂性,所以我觉得第一种方法更好。然而,从官方给出的解释量和逻辑文档分割的角度来看,官方似乎更倾向于后者。而后者我认为行为非常微妙。我也认为在使用多文档的同时,可以正常包含配置文件会更好,但是同时,spring.config.activate.on-profile和spring.profiles.active有些重叠,可能会造成混淆。