@ -1,5 +1,5 @@
@@ -1,5 +1,5 @@
/ *
* Copyright 2002 - 2014 the original author or authors .
* Copyright 2002 - 2015 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 .
@ -19,10 +19,15 @@ package org.springframework.scheduling.annotation;
@@ -19,10 +19,15 @@ package org.springframework.scheduling.annotation;
import java.lang.annotation.Annotation ;
import java.util.concurrent.Executor ;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
import org.springframework.aop.framework.AbstractAdvisingBeanPostProcessor ;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler ;
import org.springframework.beans.factory.BeanFactory ;
import org.springframework.beans.factory.BeanFactoryAware ;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException ;
import org.springframework.core.task.TaskExecutor ;
import org.springframework.util.Assert ;
@ -54,10 +59,21 @@ import org.springframework.util.Assert;
@@ -54,10 +59,21 @@ import org.springframework.util.Assert;
* @see Async
* @see AsyncAnnotationAdvisor
* @see # setBeforeExistingAdvisors
* @see ScheduledAnnotationBeanPostProcessor
* /
@SuppressWarnings ( "serial" )
public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostProcessor implements BeanFactoryAware {
/ * *
* The default name of the { @link TaskExecutor } bean to pick up : "taskExecutor" .
* < p > Note that the initial lookup happens by type ; this is just the fallback
* in case of multiple executor beans found in the context .
* /
public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor" ;
protected final Log logger = LogFactory . getLog ( getClass ( ) ) ;
private Class < ? extends Annotation > asyncAnnotationType ;
private Executor executor ;
@ -100,9 +116,35 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostPr
@@ -100,9 +116,35 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractAdvisingBeanPostPr
this . exceptionHandler = exceptionHandler ;
}
@Override
public void setBeanFactory ( BeanFactory beanFactory ) {
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor ( this . executor , this . exceptionHandler ) ;
Executor executorToUse = this . executor ;
if ( executorToUse = = null ) {
try {
// Search for TaskExecutor bean... not plain Executor since that would
// match with ScheduledExecutorService as well, which is unusable for
// our purposes here. TaskExecutor is more clearly designed for it.
executorToUse = beanFactory . getBean ( TaskExecutor . class ) ;
}
catch ( NoUniqueBeanDefinitionException ex ) {
try {
executorToUse = beanFactory . getBean ( DEFAULT_TASK_EXECUTOR_BEAN_NAME , TaskExecutor . class ) ;
}
catch ( NoSuchBeanDefinitionException ex2 ) {
throw new IllegalStateException ( "More than one TaskExecutor bean exists within the context, " +
"and none is named 'taskExecutor'. Mark one of them as primary or name it " +
"'taskExecutor' (possibly as an alias); or specify the AsyncConfigurer interface " +
"and implement getAsyncExecutor() accordingly." , ex ) ;
}
}
catch ( NoSuchBeanDefinitionException ex ) {
logger . debug ( "Could not find default TaskExecutor bean" , ex ) ;
// Giving up -> falling back to default executor within the advisor...
}
}
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor ( executorToUse , this . exceptionHandler ) ;
if ( this . asyncAnnotationType ! = null ) {
advisor . setAsyncAnnotationType ( this . asyncAnnotationType ) ;
}