Spring @ConditionalOnThreading注解

2023/11/16

1. 简介

在这个简短的教程中,我们将研究一个相对较新的Spring Boot注解,称为@ConditionalOnThreading。

我们将介绍此注解的条件是什么以及如何满足它以创建bean。

2. 条件注解

尽管我们已经介绍了Spring Boot中的条件注解,但还是值得再次简要回顾一下它们。

条件注解提供了一种仅在满足各种特定条件时才在BeanFactory中注册Bean的方法,开发人员使用Condition接口为每个注解单独定义这些条件。

Spring Boot附带了一系列针对常见用例的预定义条件注解,常见的示例有@ConditionalOnProperty、@ConditionalOnBean和@ConditionalOnClass。

3. @ConditionalOnThreading理论

@ConditionalOnThreading只是Spring Boot中另一个预定义的条件注解,它是在3.2版本中添加的。该版本本身在撰写本文时是一个候选版本,为了访问这个候选版本,我们应该使用专用的Spring依赖仓库

仅当Spring配置为在内部使用特定类型的线程时,@ConditionalOnThreading注解才允许创建bean。线程类型意味着平台线程或虚拟线程,回想一下,自Java 21以来,我们已经能够使用虚拟线程而不是平台线程

因此,要将Spring配置为在内部使用虚拟线程,我们使用名为spring.threads.virtual.enabled的属性。如果此属性为true并且我们在Java 21或更高版本上运行,则@ConditionalOnThreading注解将允许创建bean。

4. 注解使用示例

现在让我们尝试编写一些示例来演示此注解的用例,假设我们有两个用@ConditionalOnThreading标注的bean:

@Configuration
static class CurrentConfig {

    @Bean
    @ConditionalOnThreading(Threading.PLATFORM)
    ThreadingType platformBean() {
        return ThreadingType.PLATFORM;
    }

    @Bean
    @ConditionalOnThreading(Threading.VIRTUAL)
    ThreadingType virtualBean() {
        return ThreadingType.VIRTUAL;
    }
}

enum ThreadingType {
    PLATFORM, VIRTUAL
}

因此,通过ConditionalOnThreading注解,我们将创建这两个bean之一:platformBean或virtualBean。现在让我们创建一些测试来检查此注解的工作原理:

ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner().withUserConfiguration(CurrentConfig.class);

@Test
@EnabledForJreRange(max = JRE.JAVA_20)
public void whenJava20AndVirtualThreadsDisabled_thenThreadingIsPlatform() {
    applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=false").run(context -> {
        Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.PLATFORM);
    });
}

@Test
@EnabledForJreRange(min = JRE.JAVA_21)
public void whenJava21AndVirtualThreadsEnabled_thenThreadingIsVirtual() {
    applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=true").run(context -> {
        Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.VIRTUAL);
    });
}

@Test
@EnabledForJreRange(min = JRE.JAVA_21)
public void whenJava21AndVirtualThreadsDisabled_thenThreadingIsPlatform() {
    applicationContextRunner.withPropertyValues("spring.threads.virtual.enabled=false").run(context -> {
        Assertions.assertThat(context.getBean(ThreadingType.class)).isEqualTo(ThreadingType.PLATFORM);
    });
}

在这里,我们有一个ApplicationContextRunner实例,它为测试创建一个轻量级应用程序上下文,我们用它来设置Spring属性spring.threads.virtual.enabled的值。我们还使用@EnabledForJreRange注解对测试进行了标注,该注解允许我们仅在某些Java版本上运行测试。

我们可以注意到,要使ThreadingType bean为Virtual,我们必须将该属性设置为true且至少为Java 21。在其他情况下,注解条件为false。

5. 总结

在这篇简短的文章中,我们探讨了一个新的Spring注解@ConditionalOnThreading,它作为Spring Boot 3.2的一部分提供。仅当Spring配置为通过属性在内部使用特殊类型的线程时,此注解才允许创建bean。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章