@EnableAsync+@Async源码学习笔记之三
接上一篇,本文我们进入 AsyncAnnotationBeanPostProcessor
的分析,这个类的源代码如下:
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.autoproxy.AbstractBeanFactoryAwareAdvisingPostProcessor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;/*** Bean post-processor that automatically applies asynchronous invocation* behavior to any bean that carries the {@link Async} annotation at class or* method-level by adding a corresponding {@link AsyncAnnotationAdvisor} to the* exposed proxy (either an existing AOP proxy or a newly generated proxy that* implements all of the target's interfaces).** <p>The {@link TaskExecutor} responsible for the asynchronous execution may* be provided as well as the annotation type that indicates a method should be* invoked asynchronously. If no annotation type is specified, this post-* processor will detect both Spring's {@link Async @Async} annotation as well* as the EJB 3.1 {@code javax.ejb.Asynchronous} annotation.** <p>For methods having a {@code void} return type, any exception thrown* during the asynchronous method invocation cannot be accessed by the* caller. An {@link AsyncUncaughtExceptionHandler} can be specified to handle* these cases.** <p>Note: The underlying async advisor applies before existing advisors by default,* in order to switch to async execution as early as possible in the invocation chain.** @author Mark Fisher* @author Juergen Hoeller* @author Stephane Nicoll* @since 3.0* @see Async* @see AsyncAnnotationAdvisor* @see #setBeforeExistingAdvisors* @see ScheduledAnnotationBeanPostProcessor*/
@SuppressWarnings("serial")
public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor {/*** 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.* @since 4.2* @see AnnotationAsyncExecutionInterceptor#DEFAULT_TASK_EXECUTOR_BEAN_NAME*/public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME =AnnotationAsyncExecutionInterceptor.DEFAULT_TASK_EXECUTOR_BEAN_NAME;protected final Log logger = LogFactory.getLog(getClass());@Nullableprivate Class<? extends Annotation> asyncAnnotationType;@Nullableprivate Executor executor;@Nullableprivate AsyncUncaughtExceptionHandler exceptionHandler;public AsyncAnnotationBeanPostProcessor() {setBeforeExistingAdvisors(true);}/*** Set the 'async' annotation type to be detected at either class or method* level. By default, both the {@link Async} annotation and the EJB 3.1* {@code javax.ejb.Asynchronous} annotation will be detected.* <p>This setter property exists so that developers can provide their own* (non-Spring-specific) annotation type to indicate that a method (or all* methods of a given class) should be invoked asynchronously.* @param asyncAnnotationType the desired annotation type*/public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) {Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null");this.asyncAnnotationType = asyncAnnotationType;}/*** Set the {@link Executor} to use when invoking methods asynchronously.* <p>If not specified, default executor resolution will apply: searching for a* unique {@link TaskExecutor} bean in the context, or for an {@link Executor}* bean named "taskExecutor" otherwise. If neither of the two is resolvable,* a local default executor will be created within the interceptor.* @see AsyncAnnotationAdvisor#AsyncAnnotationAdvisor(Executor, AsyncUncaughtExceptionHandler)* @see AnnotationAsyncExecutionInterceptor#getDefaultExecutor(BeanFactory)* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME*/public void setExecutor(Executor executor) {this.executor = executor;}/*** Set the {@link AsyncUncaughtExceptionHandler} to use to handle uncaught* exceptions thrown by asynchronous method executions.* @since 4.1*/public void setExceptionHandler(AsyncUncaughtExceptionHandler exceptionHandler) {this.exceptionHandler = exceptionHandler;}@Overridepublic void setBeanFactory(BeanFactory beanFactory) {super.setBeanFactory(beanFactory);// 重点就是这个 AsyncAnnotationAdvisorAsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);if (this.asyncAnnotationType != null) {advisor.setAsyncAnnotationType(this.asyncAnnotationType);}advisor.setBeanFactory(beanFactory);this.advisor = advisor;}}
setAsyncAnnotationType
setExecutor
setExceptionHandler
这三个方法,看过前面文章的都知道是干嘛的了。这里再啰嗦下:
setAsyncAnnotationType
方法,给成员变量asyncAnnotationType
赋值,其值来自@EnableAsync
的annotation
属性的值。setExecutor
方法,给成员变量executor
赋值,其值来自AsyncConfigurer
的getAsyncExecutor
方法的返回值。setExceptionHandler
方法,给成员变量exceptionHandler
赋值,其值来自AsyncConfigurer
的getAsyncUncaughtExceptionHandler
方法的返回值。
重点是 setBeanFactory
这个方法,它里边的核心就是创建了一个 AsyncAnnotationAdvisor
,看这名字就知道转入AOP相关的知识了。
至此,重点就转移到 AsyncAnnotationAdvisor
这个类了,下一篇文章我们来分析它。