1. Introduction
1.导言
In this quick tutorial, we’re going to look into a relatively new Spring Boot annotation called @ConditionalOnThreading.
在本快速教程中,我们将了解一个相对较新的 Spring Boot 注释,名为 @ConditionalOnThreading 。
We’ll discover what this annotation’s condition is and how to satisfy it in order to create the bean.
我们将了解该注解的条件是什么,以及如何满足该条件以创建 Bean。
2. Conditional Annotations
2.条件注释
Although we’ve already covered conditional annotations in Spring Boot, it’s worth very briefly recalling them again.
虽然我们已经介绍过 Spring Boot 中的条件注解,但还是值得再次简要回顾一下。
Conditional annotations provide a way to register a bean in BeanFactory only if various specific conditions are met. Developers define these conditions for each annotation individually by using the Condition interface.
条件注解提供了一种仅在满足各种特定条件时才在 BeanFactory 中注册 Bean 的方法。开发人员通过使用 Condition 接口为每个注解单独定义这些条件。
Spring Boot comes with a bunch of pre-defined Conditional annotations for common use cases. The common examples are @ConditionalOnProperty, @ConditionalOnBean, and @ConditionalOnClass.
Spring Boot 为常见用例提供了大量预定义的条件注解。常见的示例有 @ConditionalOnProperty、@ConditionalOnBean 和 @ConditionalOnClass。
3. @ConditionalOnThreading Theory
3.@ConditionalOnThreading 理论
@ConditionalOnThreading is just another pre-defined conditional annotation in Spring Boot. It was added in version 3.2, which was itself a release candidate at the time of the article’s creation. To get early access to this release candidate, we should use the dedicated Spring artifacts repo.
@ConditionalOnThreading 是 Spring Boot 中另一个预定义的条件注解。它是在 3.2 版本中添加的,在本文创建时,该版本本身还是候选发布版。要尽早访问该候选发布版本,我们应使用专用的 Spring 工件仓库。
The @ConditionalOnThreading annotation allows the creation of a bean only if Spring is configured to use a specific type of threading internally. By type of threads, it means either the platform threads or virtual threads. To recall, since Java 21, we have had the ability to use virtual threads instead of platform ones.
只有当 Spring 被配置为在内部使用特定类型的线程时,@ConditionalOnThreading 注解才允许创建 Bean。所谓线程类型,指的是平台线程或虚拟线程。回顾一下,从 Java 21 开始,我们就可以使用虚拟线程来代替平台线程。
So, to configure Spring to use virtual threads internally, we use a property named spring.threads.virtual.enabled. If this property is true and we’re running on Java 21 or higher, then @ConditionalOnThreading annotation would allow the creation of the bean.
因此,为了配置 Spring 在内部使用虚拟线程,我们使用了名为 spring.threads.virtual.enabled 的属性。如果该属性为 true,并且我们在 Java 21 或更高版本上运行,那么 @ConditionalOnThreading 注解将允许创建 Bean。
4. Annotation Usage Sample
4.注释使用示例
Let’s now try to write some examples to demonstrate the use cases of this annotation. Let’s assume we have two beans annotated with @ConditionalOnThreading:
现在,让我们试着编写一些示例来演示该注解的用例。假设我们有两个使用 @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
}
So, with the ConditionalOnThreading annotation, we’ll have one of these two beans created: either the platformBean or virtualBean. Let’s now create some tests to check how this annotation works:
因此,通过 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);
});
}
Here, we have an ApplicationContextRunner instance that creates a lightweight application context for tests. We use it to set up the value of the spring property spring.threads.virtual.enabled. We’ve also annotated the tests with @EnabledForJreRange annotation. This annotation allows us to run tests only on certain Java versions.
在这里,我们有一个 ApplicationContextRunner 实例,它为测试创建了一个轻量级应用程序上下文。我们使用它来设置 spring 属性 spring.threads.virtual.enabled 的值。我们还为测试添加了 @EnabledForJreRange 注解。该注解允许我们仅在特定 Java 版本上运行测试。
As we can notice, for the ThreadingType bean to be Virtual, we must have the property set to true and at least Java 21. In other cases, the annotation condition is false.
正如我们所注意到的,要使 ThreadingType Bean 成为 Virtual Bean,我们必须将该属性设置为 true,并且至少为 Java 21。在其他情况下,注解条件为 false。
5. Conclusion
5.结论
In this short article, we’ve explored a new Spring annotation – @ConditionalOnThreading. It is available as a part of Spring Boot 3.2. This annotation allows the creation of the bean only if Spring is configured to use a special kind of threading internally via property.
在这篇短文中,我们探讨了一个新的 Spring 注释 – @ConditionalOnThreading。它是 Spring Boot 3.2 的一部分。只有在 Spring 通过属性配置为在内部使用一种特殊的线程时,该注解才允许创建 Bean。
As always, the source code for the article is available over on GitHub.
一如既往,本文的源代码可在 GitHub 上获取。