动态

详情 返回 返回

《底層到底做了什麼》--- spring 的@Async - 动态 详情

上文已經講過@EnableAsync的bean構建過程,這裏繼續講解@Async執行過程。@Async執行過程是spring的一個AOP調用過程。

代碼

public class ApiGatewayApplication {

  public static void main(String[] args) {
    SpringApplication.run(ApiGatewayApplication.class, args);

    AsyncTest test = BeanUtils.getBean("asyncTest");
    test.test();//1
  }
}

@Configuration
public class WorkPool {
    @Bean("WorkPool")
    public ThreadPoolTaskExecutor  taskExecutor(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

@Component
public class AsyncTest {

    @Async
    public void test() {
        System.out.printf("test"); 
    }

}

執行流程

1、調用@Async修飾的方法。
(1)如果沒有AOP行為,直接調用原bean。
(2)如果有AOP行為,構造一個 Cglib的CglibMethodInvocation對象並觸發。


    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

        @Nullable
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                Object retVal;
                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = methodProxy.invoke(target, argsToUse);//(1)
                } else {
                    retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();//(2)
                } 
}

2、通過@Async註解,找到AsyncExecutionInterceptor執行器

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
 public Object proceed() throws Throwable {
        
            Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
                return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
            } else {
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);//2
            }
        }
    }

3、通過doSubmit將任務發給TaskExecutor,實現Async異步的功能。其中,ThreadPoolTaskExecutor就是在demo中定義的WorkPool。

public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered {
 @Nullable
    public Object invoke(MethodInvocation invocation) throws Throwable {

 return this.doSubmit(task, executor, invocation.getMethod().getReturnType()); 
 }

 public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {
public <T> Future<T> submit(Callable<T> task) { //3
        ThreadPoolExecutor executor = this.getThreadPoolExecutor();

        try {
            return executor.submit(task);
        } catch (RejectedExecutionException var4) {
            throw new TaskRejectedException("Executor [" + executor + "] did not accept task: " + task, var4);
        }
    }
 }

實現Asyn異步調用。

user avatar simonbaker_5ec61c266b1df 头像 gkymfrg1 头像 zzger 头像 huangxunhui 头像 5n7qfpo1 头像 coderdd 头像 slnongchang 头像 java_3y 头像 aishang 头像
点赞 9 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.