Skip to content

Commit 122f2c9

Browse files
committed
Make IntegrationTaskSchedulerConfiguration virtual threads aware
1 parent 9e3e067 commit 122f2c9

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,19 @@
3232
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3333
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3434
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
35+
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
3536
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
3637
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
3738
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
3839
import org.springframework.boot.autoconfigure.jmx.JmxProperties;
3940
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
4041
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
4142
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
43+
import org.springframework.boot.autoconfigure.thread.Threading;
4244
import org.springframework.boot.context.properties.EnableConfigurationProperties;
4345
import org.springframework.boot.context.properties.PropertyMapper;
4446
import org.springframework.boot.context.properties.source.MutuallyExclusiveConfigurationPropertiesException;
47+
import org.springframework.boot.task.SimpleAsyncTaskSchedulerBuilder;
4548
import org.springframework.boot.task.ThreadPoolTaskSchedulerBuilder;
4649
import org.springframework.context.annotation.Bean;
4750
import org.springframework.context.annotation.Conditional;
@@ -65,6 +68,7 @@
6568
import org.springframework.messaging.rsocket.RSocketStrategies;
6669
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
6770
import org.springframework.scheduling.Trigger;
71+
import org.springframework.scheduling.concurrent.SimpleAsyncTaskScheduler;
6872
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
6973
import org.springframework.scheduling.support.CronTrigger;
7074
import org.springframework.scheduling.support.PeriodicTrigger;
@@ -79,6 +83,7 @@
7983
* @author Stephane Nicoll
8084
* @author Vedran Pavic
8185
* @author Madhura Bhave
86+
* @author Yong-Hyun Kim
8287
* @since 1.1.0
8388
*/
8489
@AutoConfiguration(after = { DataSourceAutoConfiguration.class, JmxAutoConfiguration.class,
@@ -169,15 +174,24 @@ private Trigger createPeriodicTrigger(Duration period, Duration initialDelay, bo
169174
* scheduling explicitly.
170175
*/
171176
@Configuration(proxyBeanMethods = false)
172-
@ConditionalOnBean(ThreadPoolTaskSchedulerBuilder.class)
173177
@ConditionalOnMissingBean(name = IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)
174178
protected static class IntegrationTaskSchedulerConfiguration {
175179

176180
@Bean(name = IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)
181+
@ConditionalOnBean(ThreadPoolTaskSchedulerBuilder.class)
182+
@ConditionalOnThreading(Threading.PLATFORM)
177183
public ThreadPoolTaskScheduler taskScheduler(ThreadPoolTaskSchedulerBuilder threadPoolTaskSchedulerBuilder) {
178184
return threadPoolTaskSchedulerBuilder.build();
179185
}
180186

187+
@Bean(name = IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)
188+
@ConditionalOnBean(SimpleAsyncTaskSchedulerBuilder.class)
189+
@ConditionalOnThreading(Threading.VIRTUAL)
190+
public SimpleAsyncTaskScheduler taskSchedulerVirtualThreads(
191+
SimpleAsyncTaskSchedulerBuilder simpleAsyncTaskSchedulerBuilder) {
192+
return simpleAsyncTaskSchedulerBuilder.build();
193+
}
194+
181195
}
182196

183197
/**

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import io.rsocket.transport.netty.client.TcpClientTransport;
3333
import org.assertj.core.api.InstanceOfAssertFactories;
3434
import org.junit.jupiter.api.Test;
35+
import org.junit.jupiter.api.condition.EnabledForJreRange;
36+
import org.junit.jupiter.api.condition.JRE;
3537
import reactor.core.publisher.Mono;
3638

3739
import org.springframework.beans.DirectFieldAccessor;
@@ -54,9 +56,11 @@
5456
import org.springframework.boot.sql.init.DatabaseInitializationMode;
5557
import org.springframework.boot.sql.init.DatabaseInitializationSettings;
5658
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
59+
import org.springframework.boot.testsupport.assertj.SimpleAsyncTaskExecutorAssert;
5760
import org.springframework.context.annotation.Bean;
5861
import org.springframework.context.annotation.Configuration;
5962
import org.springframework.context.annotation.Primary;
63+
import org.springframework.core.task.SimpleAsyncTaskExecutor;
6064
import org.springframework.integration.annotation.IntegrationComponentScan;
6165
import org.springframework.integration.annotation.MessagingGateway;
6266
import org.springframework.integration.annotation.ServiceActivator;
@@ -84,6 +88,7 @@
8488
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
8589
import org.springframework.messaging.support.GenericMessage;
8690
import org.springframework.scheduling.TaskScheduler;
91+
import org.springframework.scheduling.concurrent.SimpleAsyncTaskScheduler;
8792
import org.springframework.scheduling.support.CronTrigger;
8893
import org.springframework.scheduling.support.PeriodicTrigger;
8994
import org.springframework.test.util.ReflectionTestUtils;
@@ -98,6 +103,7 @@
98103
* @author Artem Bilan
99104
* @author Stephane Nicoll
100105
* @author Vedran Pavic
106+
* @author Yong-Hyun Kim
101107
*/
102108
class IntegrationAutoConfigurationTests {
103109

@@ -521,6 +527,18 @@ void integrationManagementInstrumentedWithObservation() {
521527
});
522528
}
523529

530+
@Test
531+
@EnabledForJreRange(min = JRE.JAVA_21)
532+
void integrationVirtualThreadsEnabled() {
533+
this.contextRunner.withPropertyValues("spring.threads.virtual.enabled=true")
534+
.run((context) -> assertThat(context).hasSingleBean(TaskScheduler.class)
535+
.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class)
536+
.isInstanceOf(SimpleAsyncTaskScheduler.class)
537+
.satisfies((taskScheduler) -> SimpleAsyncTaskExecutorAssert
538+
.assertThat((SimpleAsyncTaskExecutor) taskScheduler)
539+
.usesVirtualThreads()));
540+
}
541+
524542
@Configuration(proxyBeanMethods = false)
525543
static class CustomMBeanExporter {
526544

0 commit comments

Comments
 (0)