Spring Async异步处理源码解读

105 阅读4分钟

Spring Async异步处理源码解读

小编微信:372787553 进入社区交流群

在项目想实用异步的处理方式时,spring为我们提供了解决方案,就在在类或者方法上添加@Async的注解,当然如果写在类上代表整个类都是异步处理的方式,今天我们就来揭晓一下为何在方法上添加一个@Async的注解就可以让方法变成异步处理的方式.本文的分析,是基于spring 5.2.6.RELEASE | 2.3.1.RELEASE的版本进行分析学习

EnableAsync

在spring中,如果你想实用@Async的功能,需要在启动类添加@EnableAsync

@EnableAsync
@SpringBootApplication
public class OkHttpAppStart {
    public static void main(String[] args) {
        SpringApplication.run(OkHttpAppStart.class, args);
    }
}

我们来看看为甚在启动类添加了此注解就可以将方法变成异步的,它到底做了什么?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 重点在这里 async的配置类
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {

	/**
	 * 指示要在类或方法级别检测的“异步”注释类型。
	 * 此属性的存在使得开发人员可以提供自己的自定义注释类型,以指示应异步调用方法(或给定类的所有方法)
	 */
	Class<? extends Annotation> annotation() default Annotation.class;

	boolean proxyTargetClass() default false;

	/**
	 *
	 * 指示应如何应用异步建议。
	 * 默认值为AdviceMode.PROXY。请注意,代理模式仅允许通过代理拦截呼叫。
	 * 同一类中的本地调用不能以这种方式被拦 截;在本地调用中,对这样的方法的Async注释将被忽略,
	 * 因为Spring的拦截器甚至不参与这样的运行时场景。对于更高级的拦截模式,
	 * 请考虑将其切换到AdviceMode.ASPECTJ。
	 * 
	 */
	AdviceMode mode() default AdviceMode.PROXY;

	/**
	 * 直接加载顺序,
	 */
	int order() default Ordered.LOWEST_PRECEDENCE;

}

AsyncConfigurationSelector

public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {

   private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
         "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";


   /**
    * Returns {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration}
    * for {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()},
    * respectively.
    */
   @Override
   @Nullable
   public String[] selectImports(AdviceMode adviceMode) {
      switch (adviceMode) {
         case PROXY:
            return new String[] {ProxyAsyncConfiguration.class.getName()};
         case ASPECTJ:
            return new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};
         default:
            return null;
      }
   }

}

默认走的是PROXY,通过ProxyAsyncConfiguration生成AsyncAnnotationBeanPostProcessor对象

AsyncAnnotationBeanPostProcessor

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());
	// 线程执行器
   @Nullable
   private Supplier<Executor> executor;
	// 异常处理器
   @Nullable
   private Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;
	// 扫描注解的类型
   @Nullable
   private Class<? extends Annotation> asyncAnnotationType;
   // ...
   // 生成代理对象,回调后 AsyncAnnotationAdvisor对象
	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		super.setBeanFactory(beanFactory);

		AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
		if (this.asyncAnnotationType != null) {
			advisor.setAsyncAnnotationType(this.asyncAnnotationType);
		}
		advisor.setBeanFactory(beanFactory);
		this.advisor = advisor;
	} 
}    

AsyncAnnotationAdvisor

//构建 异步advisor	
public AsyncAnnotationAdvisor(
			@Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {

		Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
    	 //@Async注解作为切点
		asyncAnnotationTypes.add(Async.class);
		try {
			asyncAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
		}
		catch (ClassNotFoundException ex) {
			// If EJB 3.1 API not present, simply ignore.
		}
     	//赋值advice 为 AnnotationAsyncExecutionInterceptor
    	//会将 线程执行器和异常处理器放入进去,不过我们一般不去自定义的话,这个时候是null,他会处理走默认的
		this.advice = buildAdvice(executor, exceptionHandler);
    	//根据@Async生成对应的切点
		this.pointcut = buildPointcut(asyncAnnotationTypes);
	}

AsyncExecutionAspectSupport.buildAdvice

创建AnnotationAsyncExecutionInterceptor

protected Advice buildAdvice(
      @Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {

   AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
   interceptor.configure(executor, exceptionHandler);
   return interceptor;
}

这里需要追溯到父类AsyncExecutionAspectSupport

public AsyncExecutionAspectSupport(@Nullable Executor defaultExecutor) {
   this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
   this.exceptionHandler = SingletonSupplier.of(SimpleAsyncUncaughtExceptionHandler::new);
}

getDefaultExecutor(this.beanFactory));方法就是会去获取默认的线程执行器 会先去单例池中获取,如果没有才会自己创建。 在下方会调用到!

getDefaultExecutor的大概逻辑就是:

先去spring容器中获取 TaskExecutor.class 的实例 -> 没有再去spring容器中获取beanName = "taskExecutor" 的实例

protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
		if (beanFactory != null) {
			try {
				return beanFactory.getBean(TaskExecutor.class);
			}
			catch (NoUniqueBeanDefinitionException ex) {
				logger.debug("Could not find unique TaskExecutor bean", ex);
				try {
					return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
				}
				catch (NoSuchBeanDefinitionException ex2) {
					
				}
			}
			catch (NoSuchBeanDefinitionException ex) {
				logger.debug("Could not find default TaskExecutor bean", ex);
				try {
					return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
				}
				catch (NoSuchBeanDefinitionException ex2) {
					
				}
				// Giving up -> either using local default executor or none at all...
			}
		}
		return null;
	}

再没有 自己去创建 new SimpleAsyncTaskExecutor()

返回到子类AsyncExecutionInterceptor

protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
   Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
   return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
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);
		if (executor == null) {
			throw new IllegalStateException(
					"No executor specified and no default executor set on AsyncExecutionInterceptor either");
		}

		Callable<Object> task = () -> {
			try {
                 //内部执行 目标对象逻辑
				Object result = invocation.proceed();
				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());
	}


protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
        AsyncTaskExecutor executor = this.executors.get(method);
        if (executor == null) {
            Executor targetExecutor;
            //根据@Async注解上value值 ,判断是否有指定的TaskExecutor或Executor执行器
            String qualifier = getExecutorQualifier(method);
            if (StringUtils.hasLength(qualifier)) {
                targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
            }
            else {
                //调用 表达式方法 这个get实际上调用方法是 getDefaultExecutor(this.beanFactory))
                //如果没有在spring容器中创建线程池的单例的话  拿到的是 SimpleAsyncTaskExecutor()对象
                targetExecutor = this.defaultExecutor.get();
            }
            if (targetExecutor == null) {
                return null;
            }
            executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
                    (AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
            this.executors.put(method, executor);
        }
        //返回线程执行器
        return executor;
    }


protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
        if (CompletableFuture.class.isAssignableFrom(returnType)) {
            return CompletableFuture.supplyAsync(() -> {
                try {
                    return task.call();
                }
                catch (Throwable ex) {
                    throw new CompletionException(ex);
                }
            }, executor);
        }
        //ListenableFuture 类型
        else if (ListenableFuture.class.isAssignableFrom(returnType)) {
            return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
        }
        //Future类型
        else if (Future.class.isAssignableFrom(returnType)) {
            return executor.submit(task);
        }
        else {
            //直接 执行
            executor.submit(task);
            return null;
        }
    }