Consistently accept "taskExecutor" bean of type Executor (as stated in @EnableAsync's javadoc)
Issue: SPR-15566
This commit is contained in:
		
							parent
							
								
									0287a74d69
								
							
						
					
					
						commit
						3cc94ae8b5
					
				|  | @ -1,5 +1,5 @@ | |||
| /* | ||||
|  * Copyright 2002-2016 the original author or authors. | ||||
|  * Copyright 2002-2017 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. | ||||
|  | @ -221,6 +221,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { | |||
| 				return beanFactory.getBean(TaskExecutor.class); | ||||
| 			} | ||||
| 			catch (NoUniqueBeanDefinitionException ex) { | ||||
| 				logger.debug("Could not find unique TaskExecutor bean", ex); | ||||
| 				try { | ||||
| 					return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class); | ||||
| 				} | ||||
|  | @ -234,8 +235,14 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { | |||
| 			} | ||||
| 			catch (NoSuchBeanDefinitionException ex) { | ||||
| 				logger.debug("Could not find default TaskExecutor bean", ex); | ||||
| 				try { | ||||
| 					return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class); | ||||
| 				} | ||||
| 				catch (NoSuchBeanDefinitionException ex2) { | ||||
| 					logger.info("No task executor bean found for async processing: " + | ||||
| 							"no bean of type TaskExecutor and no bean named 'taskExecutor' either"); | ||||
| 				} | ||||
| 				// Giving up -> either using local default executor or none at all... | ||||
| 				logger.info("No TaskExecutor bean found for async processing"); | ||||
| 			} | ||||
| 		} | ||||
| 		return null; | ||||
|  |  | |||
|  | @ -219,6 +219,7 @@ public class ScheduledAnnotationBeanPostProcessor | |||
| 				this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, false)); | ||||
| 			} | ||||
| 			catch (NoUniqueBeanDefinitionException ex) { | ||||
| 				logger.debug("Could not find unique TaskScheduler bean", ex); | ||||
| 				try { | ||||
| 					this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, true)); | ||||
| 				} | ||||
|  | @ -239,6 +240,7 @@ public class ScheduledAnnotationBeanPostProcessor | |||
| 					this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, false)); | ||||
| 				} | ||||
| 				catch (NoUniqueBeanDefinitionException ex2) { | ||||
| 					logger.debug("Could not find unique ScheduledExecutorService bean", ex2); | ||||
| 					try { | ||||
| 						this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, true)); | ||||
| 					} | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ import java.lang.annotation.Target; | |||
| import java.lang.reflect.Method; | ||||
| import java.util.concurrent.ExecutionException; | ||||
| import java.util.concurrent.Executor; | ||||
| import java.util.concurrent.Executors; | ||||
| import java.util.concurrent.Future; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
|  | @ -42,6 +43,7 @@ import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.core.Ordered; | ||||
| import org.springframework.scheduling.concurrent.CustomizableThreadFactory; | ||||
| import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||||
| import org.springframework.stereotype.Component; | ||||
| import org.springframework.util.ReflectionUtils; | ||||
|  | @ -180,9 +182,23 @@ public class EnableAsyncTests { | |||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void customExecutorIsPropagated() throws InterruptedException { | ||||
| 	public void customExecutorBean() throws InterruptedException { | ||||
| 		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); | ||||
| 		ctx.register(CustomExecutorAsyncConfig.class); | ||||
| 		ctx.register(CustomExecutorBean.class); | ||||
| 		ctx.refresh(); | ||||
| 
 | ||||
| 		AsyncBean asyncBean = ctx.getBean(AsyncBean.class); | ||||
| 		asyncBean.work(); | ||||
| 		Thread.sleep(500); | ||||
| 		assertThat(asyncBean.getThreadOfExecution().getName(), startsWith("Custom-")); | ||||
| 
 | ||||
| 		ctx.close(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void customExecutorConfig() throws InterruptedException { | ||||
| 		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); | ||||
| 		ctx.register(CustomExecutorConfig.class); | ||||
| 		ctx.refresh(); | ||||
| 
 | ||||
| 		AsyncBean asyncBean = ctx.getBean(AsyncBean.class); | ||||
|  | @ -381,7 +397,23 @@ public class EnableAsyncTests { | |||
| 
 | ||||
| 	@Configuration | ||||
| 	@EnableAsync | ||||
| 	static class CustomExecutorAsyncConfig implements AsyncConfigurer { | ||||
| 	static class CustomExecutorBean { | ||||
| 
 | ||||
| 		@Bean | ||||
| 		public AsyncBean asyncBean() { | ||||
| 			return new AsyncBean(); | ||||
| 		} | ||||
| 
 | ||||
| 		@Bean | ||||
| 		public Executor taskExecutor() { | ||||
| 			return Executors.newSingleThreadExecutor(new CustomizableThreadFactory("Custom-")); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Configuration | ||||
| 	@EnableAsync | ||||
| 	static class CustomExecutorConfig implements AsyncConfigurer { | ||||
| 
 | ||||
| 		@Bean | ||||
| 		public AsyncBean asyncBean() { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue