From ab1b3104bbc58903bae1131c49f21f51b7dab85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Thu, 27 Mar 2025 15:01:38 +0100 Subject: [PATCH] Polish "Allow configuring a TaskExecutor even if an Executor is present" See gh-44659 --- .../task/TaskExecutorConfigurations.java | 4 +--- .../TaskExecutionAutoConfigurationTests.java | 22 ++++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations.java index c09e4df2f0..ffecc01442 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations.java @@ -37,7 +37,6 @@ import org.springframework.context.annotation.Lazy; import org.springframework.core.task.SimpleAsyncTaskExecutor; import org.springframework.core.task.TaskDecorator; import org.springframework.core.task.TaskExecutor; -import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor; import org.springframework.scheduling.annotation.AsyncConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -146,8 +145,7 @@ class TaskExecutorConfigurations { } @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(name = AsyncAnnotationBeanPostProcessor.DEFAULT_TASK_EXECUTOR_BEAN_NAME, - value = AsyncConfigurer.class) + @ConditionalOnMissingBean(AsyncConfigurer.class) static class AsyncConfigurerConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java index 004c350b09..0432d70f5e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionOverrideException; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.task.SimpleAsyncTaskExecutorBuilder; @@ -239,6 +240,21 @@ class TaskExecutionAutoConfigurationTests { .isInstanceOf(BeanDefinitionOverrideException.class)); } + @Test + void taskExecutorWhenModeIsForceAndHasCustomBFPPCanRestoreTaskExecutorAlias() { + this.contextRunner.withBean("customTaskExecutor", Executor.class, SyncTaskExecutor::new) + .withPropertyValues("spring.task.execution.mode=force") + .withBean(BeanFactoryPostProcessor.class, + () -> (beanFactory) -> beanFactory.registerAlias("applicationTaskExecutor", "taskExecutor")) + .run((context) -> { + assertThat(context.getBeansOfType(Executor.class)).hasSize(2) + .containsKeys("customTaskExecutor", "applicationTaskExecutor"); + assertThat(context).hasBean("taskExecutor"); + assertThat(context.getBean("taskExecutor")).isSameAs(context.getBean("applicationTaskExecutor")); + + }); + } + @Test @EnabledForJreRange(min = JRE.JAVA_21) void whenVirtualThreadsAreEnabledAndCustomTaskExecutorIsDefinedThenSimpleAsyncTaskExecutorThatUsesVirtualThreadsBacksOff() { @@ -294,18 +310,18 @@ class TaskExecutionAutoConfigurationTests { } @Test - void enableAsyncUsesCustomExecutorWhenModeIsForceAndHasCustomTaskExecutorWithReservedName() { + void enableAsyncUsesAutoConfiguredExecutorWhenModeIsForceAndHasCustomTaskExecutorWithReservedName() { this.contextRunner .withPropertyValues("spring.task.execution.thread-name-prefix=auto-task-", "spring.task.execution.mode=force") .withBean("taskExecutor", Executor.class, () -> createCustomAsyncExecutor("custom-task-")) .withUserConfiguration(AsyncConfiguration.class, TestBean.class) .run((context) -> { - assertThat(context).doesNotHaveBean(AsyncConfigurer.class); + assertThat(context).hasSingleBean(AsyncConfigurer.class); assertThat(context.getBeansOfType(Executor.class)).hasSize(2); TestBean bean = context.getBean(TestBean.class); String text = bean.echo("something").get(); - assertThat(text).contains("custom-task-").contains("something"); + assertThat(text).contains("auto-task-").contains("something"); }); }