Insight spring @Async 工作机制

暴博远
2023-12-01

疑问:@Async 是怎样解析的,spring如何实现注解方法的异步调用?

...

0、@Async 的应用: Creating Asynchronous Methods

...

1、@Async 的作用

按照惯例,annotation 是bean-post-processor处理的。处理@Async 的processor 就是在解析task:annotation-driven 配置过程中注册的,参考Insight task:annotation-driven 解析

看看注册的AsyncAnnotationBeanPostProcessor 做了什么:

a.processor 指定属性advisor默认为AsyncAnnotationAdvisor,至此可以知道spring 异步方法支持是通过AOP 实现的!

b.哪些类会创建proxy,判断bean class是否有@Async 或者method 有@Async(see AsyncAnnotationAdvisor.pointcut)。

...

2、异步方法实现:

AsyncAnnotationAdvisor.advice = new AnnotationAsyncExecutionInterceptor(executor)

直接上AnnotationAsyncExecutionInterceptor源码:

/**
 * Intercept the given method invocation, 
 * submit the actual calling of the method to the correct task executor and return immediately to the caller.
 */
public Object invoke(final MethodInvocation invocation) throws Throwable {
    Class
   
    targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
    specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
    
    AsyncTaskExecutor executor = determineAsyncExecutor(specificMethod);
    if (executor == null) {
	    throw new IllegalStateException("No executor specified and no default executor set on AsyncExecutionInterceptor either");
    }
    // 熟悉的Executor、Future
    Future
   
    result = executor.submit(
        	new Callable() {
                public Object call() throws Exception {
                    try {
                        Object result = invocation.proceed();
                        if (result instanceof Future) {
                            return ((Future
    
    ) result).get();
                        }
                    }
                    catch (Throwable ex) {
                        ReflectionUtils.rethrowException(ex);
                    }
                    return null;
                }
        	});
    
    if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {
	    return result;
    } else {
	    return null;
    }
}
看懂为什么要在call() 方法内进行result.get() 吗?@see AsyncResult 转手操作。

...

总结:

1、spring 创建异步方法是通过AOP实现的;

2、@Async 标识是否创建异步方法;

3、代理的方法需要声明为return Future。


 类似资料: