Skip to content

Commit c5491cf

Browse files
artembilansnicoll
authored andcommitted
Make Scheduler consistent for Spring Integration
Currently Spring Integration creates its own `TaskScheduler` bean if one does not exist in the context yet. When we add `@EnableScheduling`, Spring Boot auto-configures one for us, but this one comes with slightly different options than the default in Spring Integration. This commit makes sure that Spring Integration reuses the auto-configured TaskScheduler if possible, regardless of the user opting-in for `@EnabledScheduling`. See gh-25109
1 parent 78e1a81 commit c5491cf

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,7 +34,9 @@
3434
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
3535
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
3636
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
37+
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
3738
import org.springframework.boot.context.properties.EnableConfigurationProperties;
39+
import org.springframework.boot.task.TaskSchedulerBuilder;
3840
import org.springframework.context.annotation.Bean;
3941
import org.springframework.context.annotation.Conditional;
4042
import org.springframework.context.annotation.Configuration;
@@ -56,6 +58,8 @@
5658
import org.springframework.messaging.rsocket.RSocketRequester;
5759
import org.springframework.messaging.rsocket.RSocketStrategies;
5860
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
61+
import org.springframework.scheduling.TaskScheduler;
62+
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
5963
import org.springframework.util.StringUtils;
6064

6165
/**
@@ -72,9 +76,25 @@
7276
@Configuration(proxyBeanMethods = false)
7377
@ConditionalOnClass(EnableIntegration.class)
7478
@EnableConfigurationProperties(IntegrationProperties.class)
75-
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, JmxAutoConfiguration.class })
79+
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, JmxAutoConfiguration.class,
80+
TaskSchedulingAutoConfiguration.class })
7681
public class IntegrationAutoConfiguration {
7782

83+
/**
84+
* The {@link TaskScheduler} configuration.
85+
*/
86+
@Configuration(proxyBeanMethods = false)
87+
@ConditionalOnBean(TaskSchedulerBuilder.class)
88+
protected static class IntegrationTaskSchedulerConfiguration {
89+
90+
@Bean
91+
@ConditionalOnMissingBean
92+
public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
93+
return builder.build();
94+
}
95+
96+
}
97+
7898
/**
7999
* Basic Spring Integration configuration.
80100
*/

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@
3434
import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration;
3535
import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration;
3636
import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration;
37+
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
3738
import org.springframework.boot.jdbc.DataSourceInitializationMode;
3839
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3940
import org.springframework.context.annotation.Bean;
@@ -42,6 +43,7 @@
4243
import org.springframework.integration.annotation.IntegrationComponentScan;
4344
import org.springframework.integration.annotation.MessagingGateway;
4445
import org.springframework.integration.config.IntegrationManagementConfigurer;
46+
import org.springframework.integration.context.IntegrationContextUtils;
4547
import org.springframework.integration.core.MessageSource;
4648
import org.springframework.integration.endpoint.MessageProcessorMessageSource;
4749
import org.springframework.integration.gateway.RequestReplyExchanger;
@@ -56,6 +58,7 @@
5658
import org.springframework.jmx.export.MBeanExporter;
5759
import org.springframework.messaging.Message;
5860
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
61+
import org.springframework.scheduling.TaskScheduler;
5962

6063
import static org.assertj.core.api.Assertions.assertThat;
6164
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -71,7 +74,8 @@
7174
class IntegrationAutoConfigurationTests {
7275

7376
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
74-
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class));
77+
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class,
78+
TaskSchedulingAutoConfiguration.class));
7579

7680
@Test
7781
void integrationIsAvailable() {
@@ -221,6 +225,17 @@ void rsocketSupportEnabled() {
221225
});
222226
}
223227

228+
@Test
229+
void taskSchedulerAutoConfigured() {
230+
this.contextRunner
231+
.withPropertyValues("spring.task.scheduling.thread-name-prefix=integration-scheduling-",
232+
"spring.task.scheduling.pool.size=3")
233+
.run((context) -> assertThat(context)
234+
.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class)
235+
.hasFieldOrPropertyWithValue("threadNamePrefix", "integration-scheduling-")
236+
.hasFieldOrPropertyWithValue("scheduledExecutor.corePoolSize", 3));
237+
}
238+
224239
@Configuration(proxyBeanMethods = false)
225240
static class CustomMBeanExporter {
226241

spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6278,6 +6278,10 @@ Spring Boot offers several conveniences for working with {spring-integration}[Sp
62786278
Spring Integration provides abstractions over messaging and also other transports such as HTTP, TCP, and others.
62796279
If Spring Integration is available on your classpath, it is initialized through the `@EnableIntegration` annotation.
62806280

6281+
Spring Integration polling logic is based on the `TaskScheduler`.
6282+
So, it relies on the auto-configured one (see the previous section), or exposes a `taskScheduler` bean according provided `spring.task.scheduling` configuration properties.
6283+
If only Spring Integration is used, the `@EnableScheduling` annotation is optional and can be omitted on the target configuration classes.
6284+
62816285
Spring Boot also configures some features that are triggered by the presence of additional Spring Integration modules.
62826286
If `spring-integration-jmx` is also on the classpath, message processing statistics are published over JMX.
62836287
If `spring-integration-jdbc` is available, the default database schema can be created on startup, as shown in the following line:

0 commit comments

Comments
 (0)