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
pull/25178/head
Artem Bilan 4 years ago committed by Stephane Nicoll
parent 78e1a812e2
commit c5491cfdd7

@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -34,7 +34,9 @@ import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.task.TaskSchedulerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@ -56,6 +58,8 @@ import org.springframework.integration.rsocket.outbound.RSocketOutboundGateway;
import org.springframework.messaging.rsocket.RSocketRequester;
import org.springframework.messaging.rsocket.RSocketStrategies;
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.StringUtils;
/**
@ -72,9 +76,25 @@ import org.springframework.util.StringUtils;
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(EnableIntegration.class)
@EnableConfigurationProperties(IntegrationProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, JmxAutoConfiguration.class })
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, JmxAutoConfiguration.class,
TaskSchedulingAutoConfiguration.class })
public class IntegrationAutoConfiguration {
/**
* The {@link TaskScheduler} configuration.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(TaskSchedulerBuilder.class)
protected static class IntegrationTaskSchedulerConfiguration {
@Bean
@ConditionalOnMissingBean
public ThreadPoolTaskScheduler taskScheduler(TaskSchedulerBuilder builder) {
return builder.build();
}
}
/**
* Basic Spring Integration configuration.
*/

@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -34,6 +34,7 @@ import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfig
import org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration;
import org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration;
import org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration;
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
@ -42,6 +43,7 @@ import org.springframework.context.annotation.Primary;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.config.IntegrationManagementConfigurer;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.endpoint.MessageProcessorMessageSource;
import org.springframework.integration.gateway.RequestReplyExchanger;
@ -56,6 +58,7 @@ import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jmx.export.MBeanExporter;
import org.springframework.messaging.Message;
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
import org.springframework.scheduling.TaskScheduler;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -71,7 +74,8 @@ import static org.mockito.Mockito.mock;
class IntegrationAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class));
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class,
TaskSchedulingAutoConfiguration.class));
@Test
void integrationIsAvailable() {
@ -221,6 +225,17 @@ class IntegrationAutoConfigurationTests {
});
}
@Test
void taskSchedulerAutoConfigured() {
this.contextRunner
.withPropertyValues("spring.task.scheduling.thread-name-prefix=integration-scheduling-",
"spring.task.scheduling.pool.size=3")
.run((context) -> assertThat(context)
.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class)
.hasFieldOrPropertyWithValue("threadNamePrefix", "integration-scheduling-")
.hasFieldOrPropertyWithValue("scheduledExecutor.corePoolSize", 3));
}
@Configuration(proxyBeanMethods = false)
static class CustomMBeanExporter {

@ -6278,6 +6278,10 @@ Spring Boot offers several conveniences for working with {spring-integration}[Sp
Spring Integration provides abstractions over messaging and also other transports such as HTTP, TCP, and others.
If Spring Integration is available on your classpath, it is initialized through the `@EnableIntegration` annotation.
Spring Integration polling logic is based on the `TaskScheduler`.
So, it relies on the auto-configured one (see the previous section), or exposes a `taskScheduler` bean according provided `spring.task.scheduling` configuration properties.
If only Spring Integration is used, the `@EnableScheduling` annotation is optional and can be omitted on the target configuration classes.
Spring Boot also configures some features that are triggered by the presence of additional Spring Integration modules.
If `spring-integration-jmx` is also on the classpath, message processing statistics are published over JMX.
If `spring-integration-jdbc` is available, the default database schema can be created on startup, as shown in the following line:

Loading…
Cancel
Save