1. 引言
在这个快速教程中,我们将探讨Spring Boot新引入的一个相对新颖的注解@ConditionalOnThreading
。
我们将了解这个注解的条件是什么,以及如何满足这些条件来创建bean。
2. 条件注解
虽然我们已经讨论过Spring Boot中的条件注解,但还是值得简要回顾一下。
条件注解提供了一种方法,只有在满足特定条件时才将bean注册到BeanFactory
中。开发者为每个注解单独定义这些条件,通过使用Condition
接口。
Spring Boot内置了一些常见的条件注解,例如@ConditionalOnProperty
、@ConditionalOnBean
和@ConditionalOnClass
。
3. @ConditionalOnThreading
理论
@ConditionalOnThreading
是Spring Boot中的另一个预定义条件注解。它在3.2版本中添加,而本文写作时,3.2版本还是候选发布。要获取这个候选发布的早期访问权限,应使用专用的Spring Maven仓库。
@ConditionalOnThreading
注解允许创建bean,前提是Spring配置为使用特定类型的线程(平台线程或虚拟线程)。这里的线程类型指的是平台线程或虚拟线程。回想一下,从Java 21开始,我们有能力使用虚拟线程代替平台线程。
因此,如果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上找到。