Spring中@Async注解实现原理

文章详细描述了如何使用@EnableAsync接口和相关类如ProxyAsyncConfiguration和AsyncAnnotationBeanPostProcessor来配置Spring应用中的异步任务处理,包括线程池、异常处理和自定义注解支持。
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {

}

class AsyncConfigurationSelector {
    public String[] selectImports(AdviceMode adviceMode) {
        switch (adviceMode) {
            case PROXY:
                return new String[]{ProxyAsyncConfiguration.class.getName()};
            default:
                return null;
        }
    }
}

class ProxyAsyncConfiguration {
    /**
     * 注册一个处理Async注解的后置处理器,beanName为internalAsyncAnnotationProcessor
     *
     * @return
     */
    @Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
        // 创建处理注解的后置处理器
        AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor() {
            setBeforeExistingAdvisors(true);
        }
        // 手动执行配置,设置线程池和异常处理器
        bpp.configure(this.executor, this.exceptionHandler) {
            this.executor = executor;
            this.exceptionHandler = exceptionHandler;
        }
        // 获取自定义开启异步任务注解
        Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
        // 如果存在,例如@EnableAsync(annotation = LuckAsync.class)
        // 则会使用LuckAsync替换Async,只有方法上添加了LuckAsync才会异步执行,否则是正常执行
        if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
            // 设置自定义的异步注解类型
            bpp.setAsyncAnnotationType(customAsyncAnnotation);
        }
        // 设置代理类型
        bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
        // 设置顺序
        bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
        return bpp;
    }

    // ImportAware的回调方法
    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {
        // 解析EnableAsyncv注解元数据
        this.enableAsync = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableAsync.class.getName(), false));
    }

}

/**
 * 处理异步的后置处理器
 */
class AsyncAnnotationBeanPostProcessor {

    // 执行任务的线程池
    private Supplier<Executor> executor;
    // 异常处理器
    private Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;


    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        super.setBeanFactory(beanFactory) {
            this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory ? (ConfigurableListableBeanFactory) beanFactory : null);
        }
        // 创建一个切面
        AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler) {
            // 异步的注解类型
            Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
            // 默认支持@Async和@Asynchronous
            asyncAnnotationTypes.add(Async .class);
            asyncAnnotationTypes.add((Class<? extends Annotation>)ClassUtils.forName("javax.ejb.Asynchronous",AsyncAnnotationAdvisor .class);
            // 构建通知
            this.advice =

            buildAdvice(executor, exceptionHandler) {
                // 创建一个拦截器
                AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
                // 自定义配置,给拦截器设置线程池和异常处理器
                interceptor.configure(executor, exceptionHandler);
                return interceptor;
            }
            // 构建切点
            this.pointcut =

            buildPointcut(asyncAnnotationTypes) {
                ComposablePointcut result = null;
                // 遍历所有支持的注解类型
                for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
                    // 创建切点
                    Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
                    Pointcut mpc = new AnnotationMatchingPointcut(null, asyncAnnotationType, true);
                    // 创建一个可组合的切点
                    if (result == null) {
                        result = new ComposablePointcut(cpc);
                    }
                    // 将两个切点合并,内部就是合并类过滤器和方法匹配器
                    result = result.union(mpc);
                }
                // 返回创建的切点
                return (result != null ? result : Pointcut.TRUE);
            }
        }
        // 如果设置了自定义的异步注解
        if (this.asyncAnnotationType != null) {
            advisor.setAsyncAnnotationType(this.asyncAnnotationType) {
                // 默认的异步注解发生了变化,所有切点需要重新构建
                this.pointcut = buildPointcut(Sets.newHashSet(asyncAnnotationTypes));
            }
        }
        // 手动执行setBeanFactory方法
        advisor.setBeanFactory(beanFactory) {
            if (this.advice instanceof BeanFactoryAware) {
                ((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);
            }
        }
        // 保存切面
        this.advisor = advisor;
    }

    // Bean的后置方法,创建代理对象
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 如果没有切面,或者一个Aop相关的Bean,不代理
        if (this.advisor == null || bean instanceof AopInfrastructureBean) {
            return bean;
        }
        // 如果当前bean是一个由持有AOP代理工厂配置的类实现
        if (bean instanceof Advised) {
            Advised advised = (Advised) bean;
            // 判断当前代理工厂配置的类没被冻结配置,再判断上面创建的切面是否可以作用于,当前Bean
            if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
                // 在setBeanFactory创建的切面和通知
                // this.advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler)
                // 在创建当前AsyncAnnotationBeanPostProcessor后置处理器的时候设置为true了
                // 表示将当前切面放在第一位执行
                if (this.beforeExistingAdvisors) {
                    advised.addAdvisor(0, this.advisor);
                } else {
                    // 否则放在最后执行
                    advised.addAdvisor(this.advisor);
                }
                return bean;
            }
        }
        // 判断上面创建的切面是否可以作用于,当前Bean
        if (isEligible(bean, beanName)) {
            // 提前处理ProxyFactory
            ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName) {
                // 切面可用,创建代理工厂,准备创建代理对象
                if (this.beanFactory != null) {
                    // 将目标类类型保存到当前Bean的BD中
                    AutoProxyUtils.exposeTargetClass(this.beanFactory, beanName, bean.getClass());
                }
                // 创建代理工厂
                ProxyFactory proxyFactory = super.prepareProxyFactory(bean, beanName) {
                    ProxyFactory proxyFactory = new ProxyFactory();
                    proxyFactory.copyFrom(this);
                    proxyFactory.setTarget(bean);
                    return proxyFactory;
                }
                // 如果工厂配置的不是使用CBLIB代理的话,但是当前Bean的BD中设置了使用CGLIB代理,那么就使用CGLIB代理
                if (!proxyFactory.isProxyTargetClass() && this.beanFactory != null && AutoProxyUtils.shouldProxyTargetClass(this.beanFactory, beanName)) {
                    proxyFactory.setProxyTargetClass(true);
                }
                return proxyFactory;
            }
            // 如果不是使用CBLIB代理,我们要计算当前Bean需要代理的接口
            if (!proxyFactory.isProxyTargetClass()) {
                evaluateProxyInterfaces(bean.getClass(), proxyFactory) {
                    // 获取类的所有接口
                    Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
                    boolean hasReasonableProxyInterface = false;
                    // 遍历所有接口
                    for (Class<?> ifc : targetInterfaces) {
                        // 如果不是实现的Spring内部的配置接口,例如InitializingBean,DisposableBean,并且不是其他语言的接口groovy
                        // 如果符合这个条件,表示实现了有代理意义的接口
                        if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0) {
                            hasReasonableProxyInterface = true;
                            break;
                        }
                    }
                    // 如果有代理意义的接口
                    if (hasReasonableProxyInterface) {
                        // 将接口设置到工厂中,这个就可以使用JDK代理
                        for (Class<?> ifc : targetInterfaces) {
                            proxyFactory.addInterface(ifc);
                        }
                    } else {
                        // 如果没有实现有代理意义的接口,那就使用CGLIB代理
                        proxyFactory.setProxyTargetClass(true);
                    }
                }
            }
            // 将当前切面设置到代理工厂,进行切入
            proxyFactory.addAdvisor(this.advisor);
            // 自定义配置代理工厂
            customizeProxyFactory(proxyFactory);
            // 创建代理对象,详见Spring使用ProxyFactory创建代理对象源码解析
            return proxyFactory.getProxy(getProxyClassLoader());
        }
        // 如果不需要代理,则返回原始bean
        return bean;
    }
}

// 目标方法执行拦截器
// 先看文Spring中JDK动态代理和CBLIB代理的拦截逻辑
// 因为创建的代理对象调用目标方法都会执行代理对象的拦截器逻辑
// 这个拦截逻辑就是获取符合条件的所有拦截的一个集合,然后一一执行
// 我们Asycn注解的话,只有一个拦截器,就是给定的AnnotationAsyncExecutionInterceptor
public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor {
    // 拦截器的拦截方法
    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);
        // 用户定义的方法对象
        final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
        // 确定线程池
        AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod) {
            // 查询方法是否设置了指定的线程池,因为Async中,提供了value来设置指定的线程池
            AsyncTaskExecutor executor = this.executors.get(method);
            // 如果没有指定
            if (executor == null) {
                //
                Executor targetExecutor;
                // 获取指定的线程池名称
                String qualifier = getExecutorQualifier(method) {
                    // 找方法上的注解
                    Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class);
                    // 如果方法中不存在这个注解
                    if (async == null) {
                        // 找类上的注解
                        async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class);
                    }
                    // 返回value值设置的线程池名称
                    return (async != null ? async.value() : null);
                }
                // 如果设置了线程池名称
                if (StringUtils.hasLength(qualifier)) {
                    // 从Spring中获取指定名称的线程池
                    targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier) {
                        return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier) {
                            return beanFactory.getBean(qualifier, beanType);
                        }
                    }
                } else {
                    // 使用默认的线程池
                    // this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
                    targetExecutor = this.defaultExecutor.get() {
                        Executor defaultExecutor = super.getDefaultExecutor(beanFactory) {
                            if (beanFactory != null) {
                                try {
                                    // 根据类型从Spring中获取
                                    return beanFactory.getBean(TaskExecutor.class);
                                } catch (NoUniqueBeanDefinitionException ex) {
                                    try {
                                        // 如果没有,则根据"taskExecutor"来获取
                                        return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
                                    }
                                }
                            }
                        }
                        // 如果再没有使用SimpleAsyncTaskExecutor
                        return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
                    }
                }
                if (targetExecutor == null) {
                    return null;
                }
                // 将方法和方法指定的线程池绑定
                executor = (targetExecutor instanceof AsyncListenableTaskExecutor ? (AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
                this.executors.put(method, executor);
            }
            return executor;
        }
        // 如果没有线程池,抛出异常
        if (executor == null) {
            throw new IllegalStateException("No executor specified and no default executor set on AsyncExecutionInterceptor either");
        }

        // 创建Callable任务对象
        Callable<Object> task = () -> {
            try {
                // 执行下一个拦截器
                Object result = invocation.proceed();
                // 如果方法结果为Future
                if (result instanceof Future) {
                    // 直接获取结果
                    return ((Future<?>) result).get();
                }
            } catch (ExecutionException ex) {
                // 出现异常,使用异常处理器处理异常
                handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments());
            } catch (Throwable ex) {
                handleError(ex, userDeclaredMethod, invocation.getArguments());
            }
            return null;
        };
        // 提交任务
        return doSubmit(task, executor, invocation.getMethod().getReturnType()) {
            // 如果方法返回值是CompletableFuture,使用CompletableFuture提交任务
            if (CompletableFuture.class.isAssignableFrom(returnType)) {
                return CompletableFuture.supplyAsync(() -> {
                    return task.call();
                }, executor);
            }
            // 如果方法返回值是ListenableFuture,使用submitListenable提交任务
            if (ListenableFuture.class.isAssignableFrom(returnType)) {
                return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
            }
            // 如果是future或者其他的,直接实现线程池提交任务执行
            if (Future.class.isAssignableFrom(returnType)) {
                return executor.submit(task);
            }
            executor.submit(task);
            return null;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值