Skip to content

Commit 9cb9884

Browse files
committed
Consistently accept "taskExecutor" bean of type Executor (as stated in @EnableAsync's javadoc)
Issue: SPR-15566 (cherry picked from commit 3cc94ae)
1 parent ac25db6 commit 9cb9884

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.
@@ -228,6 +228,7 @@ protected Executor getDefaultExecutor(BeanFactory beanFactory) {
228228
return beanFactory.getBean(TaskExecutor.class);
229229
}
230230
catch (NoUniqueBeanDefinitionException ex) {
231+
logger.debug("Could not find unique TaskExecutor bean", ex);
231232
try {
232233
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
233234
}
@@ -241,8 +242,14 @@ protected Executor getDefaultExecutor(BeanFactory beanFactory) {
241242
}
242243
catch (NoSuchBeanDefinitionException ex) {
243244
logger.debug("Could not find default TaskExecutor bean", ex);
245+
try {
246+
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
247+
}
248+
catch (NoSuchBeanDefinitionException ex2) {
249+
logger.info("No task executor bean found for async processing: " +
250+
"no bean of type TaskExecutor and no bean named 'taskExecutor' either");
251+
}
244252
// Giving up -> either using local default executor or none at all...
245-
logger.info("No TaskExecutor bean found for async processing");
246253
}
247254
}
248255
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
@@ -221,6 +221,7 @@ private void finishRegistration() {
221221
this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, false));
222222
}
223223
catch (NoUniqueBeanDefinitionException ex) {
224+
logger.debug("Could not find unique TaskScheduler bean", ex);
224225
try {
225226
this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, true));
226227
}
@@ -241,6 +242,7 @@ private void finishRegistration() {
241242
this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, false));
242243
}
243244
catch (NoUniqueBeanDefinitionException ex2) {
245+
logger.debug("Could not find unique ScheduledExecutorService bean", ex2);
244246
try {
245247
this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, true));
246248
}

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.Ignore;
@@ -43,6 +44,7 @@
4344
import org.springframework.context.annotation.Configuration;
4445
import org.springframework.context.annotation.Lazy;
4546
import org.springframework.core.Ordered;
47+
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
4648
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
4749
import org.springframework.stereotype.Component;
4850
import org.springframework.util.ReflectionUtils;
@@ -181,9 +183,23 @@ public void aspectModeAspectJAttemptsToRegisterAsyncAspect() {
181183
}
182184

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

189205
AsyncBean asyncBean = ctx.getBean(AsyncBean.class);
@@ -382,7 +398,23 @@ public Executor otherExecutor() {
382398

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

387419
@Bean
388420
public AsyncBean asyncBean() {

0 commit comments

Comments
 (0)