Skip to content

Commit 3cc94ae

Browse files
committed
Consistently accept "taskExecutor" bean of type Executor (as stated in @EnableAsync's javadoc)
Issue: SPR-15566
1 parent 0287a74 commit 3cc94ae

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 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.
@@ -221,6 +221,7 @@ protected Executor getDefaultExecutor(BeanFactory beanFactory) {
221221
return beanFactory.getBean(TaskExecutor.class);
222222
}
223223
catch (NoUniqueBeanDefinitionException ex) {
224+
logger.debug("Could not find unique TaskExecutor bean", ex);
224225
try {
225226
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
226227
}
@@ -234,8 +235,14 @@ protected Executor getDefaultExecutor(BeanFactory beanFactory) {
234235
}
235236
catch (NoSuchBeanDefinitionException ex) {
236237
logger.debug("Could not find default TaskExecutor bean", ex);
238+
try {
239+
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
240+
}
241+
catch (NoSuchBeanDefinitionException ex2) {
242+
logger.info("No task executor bean found for async processing: " +
243+
"no bean of type TaskExecutor and no bean named 'taskExecutor' either");
244+
}
237245
// Giving up -> either using local default executor or none at all...
238-
logger.info("No TaskExecutor bean found for async processing");
239246
}
240247
}
241248
return null;

spring-context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ private void finishRegistration() {
219219
this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, false));
220220
}
221221
catch (NoUniqueBeanDefinitionException ex) {
222+
logger.debug("Could not find unique TaskScheduler bean", ex);
222223
try {
223224
this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, true));
224225
}
@@ -239,6 +240,7 @@ private void finishRegistration() {
239240
this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, false));
240241
}
241242
catch (NoUniqueBeanDefinitionException ex2) {
243+
logger.debug("Could not find unique ScheduledExecutorService bean", ex2);
242244
try {
243245
this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, true));
244246
}

spring-context/src/test/java/org/springframework/scheduling/annotation/EnableAsyncTests.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.lang.reflect.Method;
2424
import java.util.concurrent.ExecutionException;
2525
import java.util.concurrent.Executor;
26+
import java.util.concurrent.Executors;
2627
import java.util.concurrent.Future;
2728

2829
import org.junit.Test;
@@ -42,6 +43,7 @@
4243
import org.springframework.context.annotation.Configuration;
4344
import org.springframework.context.annotation.Lazy;
4445
import org.springframework.core.Ordered;
46+
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
4547
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
4648
import org.springframework.stereotype.Component;
4749
import org.springframework.util.ReflectionUtils;
@@ -180,9 +182,23 @@ public void aspectModeAspectJAttemptsToRegisterAsyncAspect() {
180182
}
181183

182184
@Test
183-
public void customExecutorIsPropagated() throws InterruptedException {
185+
public void customExecutorBean() throws InterruptedException {
184186
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
185-
ctx.register(CustomExecutorAsyncConfig.class);
187+
ctx.register(CustomExecutorBean.class);
188+
ctx.refresh();
189+
190+
AsyncBean asyncBean = ctx.getBean(AsyncBean.class);
191+
asyncBean.work();
192+
Thread.sleep(500);
193+
assertThat(asyncBean.getThreadOfExecution().getName(), startsWith("Custom-"));
194+
195+
ctx.close();
196+
}
197+
198+
@Test
199+
public void customExecutorConfig() throws InterruptedException {
200+
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
201+
ctx.register(CustomExecutorConfig.class);
186202
ctx.refresh();
187203

188204
AsyncBean asyncBean = ctx.getBean(AsyncBean.class);
@@ -381,7 +397,23 @@ public Executor otherExecutor() {
381397

382398
@Configuration
383399
@EnableAsync
384-
static class CustomExecutorAsyncConfig implements AsyncConfigurer {
400+
static class CustomExecutorBean {
401+
402+
@Bean
403+
public AsyncBean asyncBean() {
404+
return new AsyncBean();
405+
}
406+
407+
@Bean
408+
public Executor taskExecutor() {
409+
return Executors.newSingleThreadExecutor(new CustomizableThreadFactory("Custom-"));
410+
}
411+
}
412+
413+
414+
@Configuration
415+
@EnableAsync
416+
static class CustomExecutorConfig implements AsyncConfigurer {
385417

386418
@Bean
387419
public AsyncBean asyncBean() {

0 commit comments

Comments
 (0)