[spring-projects/spring-boot]@ActiveProfiles 不再支持 ${some.env:default} 属性占位符表达式

2024-06-26 486 views
6

影响: spring-test 5.3.3

回到5.2.1.RELEASE我可以使用以下命令注释测试类:

@ActiveProfiles("${testprofiles.active:test}")

当提供-Dtestprofiles.active=integrationtest上下文时将加载已解析的integrationtest配置文件:

org.springframework.core.env.StandardEnvironment - 激活配置文件 [integrationtest] com.iteratec.MyTest: 以下配置文件处于活动状态:integrationtest

升级到5.3.3后,这似乎不再起作用:

org.springframework.core.env.StandardEnvironment - 激活配置文件 [${testprofiles.active:test}] com.iteratec.MyTest:以下配置文件处于活动状态:${testprofiles.active:test}

因此就会出现回退到根本没有匹配的配置文件/基本属性的情况。

这是预期行为还是错误?


我通过使用自定义的 ActiveProfilesResolver 解决了这个问题:

@ActiveProfiles(value = "test", resolver = SystemPropertyActiveProfilesResolver.class)
public class SystemPropertyActiveProfilesResolver implements ActiveProfilesResolver {

    private final DefaultActiveProfilesResolver defaultActiveProfilesResolver = new DefaultActiveProfilesResolver();

    @Override
    public String[] resolve(Class<?> testClass) {
        Assert.notNull(testClass, "Class must not be null");

        if (System.getProperties().containsKey("spring.profiles.active")) {
            final String profiles = System.getProperty("testprofiles.active");
            return profiles.split("\\s*,\\s*");
        } else {
            return defaultActiveProfilesResolver.resolve(testClass);
        }
    }
}

回答

6

我无法使用 Spring Framework 5.2.1.RELEASE 重现此问题。

此外,我不相信 Spring Framework 曾经支持过 的属性占位符@ActiveProfiles

不过,Spring Boot Test 确实在某一时刻设置了spring.profiles.active系统属性,这会导致嵌套的占位符被解析为 Spring Environment

因此,这种行为的改变可能与 Spring Boot 有关,而与 Spring Framework 无关。

@wilkinsona,这可能与https://github.com/spring-projects/spring-boot/issues/19788有关吗?

9

我不这么认为。该问题已在使用 Framework 5.1 的 Spring Boot 2.1 中修复。@icyerasor 如果您使用的是 Spring Boot,涉及哪些版本?

2

2.3.9.RELEASE按原样使用 Spring Boot ,通过配置的配置文件中的属性占位符@ActiveProfiles将被替换。

2.3.9.RELEASE使用 Spring Framework 的Spring Boot 也是如此5.3.4

属性占位符替换不再与 Spring Boot 一起工作2.4.0(并且继续不再与 Boot 一起工作2.4.3)。

因此 Spring Boot 2.4 中一定发生了一些变化。

@wilkinsona 和 @philwebb,你们介意在 Boot 的问题跟踪器中接手这个问题吗?

2

如果 @icyerasor 确认他们正在使用 Boot,那么我们肯定应该将其转移过来。如果没有,那么我想我们需要以某种方式追踪两个更改,我们可能应该打开一个单独的 Boot 问题。

9

嗨,抱歉周末不在家。@wilkinsona 是的,我们正在使用 Boot / spring-boot-starter-test (2.4.2)。

@sbrannen 抱歉造成混淆;应该首先说明这一点,但只是@ActiveProfiles从 spring-test 中看到并因此责怪它?

3

我可以重现@sbrannen描述的内容。这一定与配置数据更改有关,因为如果spring.config.use-legacy-processing设置为,它可以与 2.4 一起使用true

我觉得奇怪的是 2.3.x 也environment.getActiveProfiles()包含${testprofiles.active:test}。但它也包含,test这就是它起作用的原因。@sbrannen${testprofiles.active:test}环境的活动配置文件中是否有预期的行为?

0

使用 2.3.9 时,如果我运行测试-Dtestprofiles.active=integrationtest并打印出活动配置文件,我会看到以下内容。

[${testprofiles.active:test},集成测试]

所以我看到了与您相同的行为,这是我以前没有注意到的。

回答你的问题,不,我不希望看到${testprofiles.active:test}注册为活跃的个人资料。

因此,谜团的一部分在于为什么占位符表达式和解析的占位符最终都成为注册的活动配置文件。

故事的另一面涉及 中的属性占位符解析是否@ActiveProfiles曾经是 Spring Boot Test 的一项有意为之的功能。我可以想象这是一个意外,但一些用户可能已经开始依赖它。因此,也许 Spring Boot 团队希望恢复该行为。另一个选择是研究在 中引入该支持spring-test

有什么想法吗?

7

它一定与配置数据的变化有关,因为如果spring.config.use-legacy-processing设置为,它就可以与 2.4 一起工作true

顺便说一句,你看得真好!

2

另一件需要记住的事情是MergedContextConfiguration(MCC),特别是关于在MCC中存储了哪些活动配置文件。

我认为未解析的属性占位符应该存储在 MCC 中,然后只解析一次,实际将其添加到——针对当时Environment可用的属性进行解析。Environment

4

另一种选择是研究在 spring-test 中引入该支持。

哦,我以为这spring-test也是受支持的东西。我不确定 Spring Boot 的支持是有意还是无意的。如果解析的属性位于诸如 之类的文件@ActiveProfiles中,情况也会变得棘手。profile-specificapplication-dev.yml

标记以引起团队注意,看看团队其他成员是否认为占位符解析@ActiveProfiles是故意的,并且我们应该支持。

3

我记不太清楚,但考虑到我们没有对此进行任何测试,我认为这不是故意的。如果到spring-test那时还不支持,我倾向于不在 Boot 中支持它。

4

我们在团队电话会议上讨论了这个问题,并决定遵循 Spring Framework,不支持 中的占位符@ActiveProfiles。这不是回归,因为它在 2.4.x 之前偶然起作用,并且该行为既未经过测试也未记录。