栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring】Spring Async 的实现原理 3 - 整体实现流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring】Spring Async 的实现原理 3 - 整体实现流程

【Spring】Spring Async 的实现原理 3 - 整体实现流程

前言@EnableAsyncAsyncConfigurationSelectorProxyAsyncConfiguration

AbstractAsyncConfigurationProxyAsyncConfiguration 总结

前言

本章节从引入 Spring Async 的 @EnableAsync 注解入手,了解下整个引入流程

@EnableAsync
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@import(AsyncConfigurationSelector.class)
public @interface EnableAsync {

	// spring async 的注解类型
	Class annotation() default Annotation.class;

	// 影响代理方式(JDK or CGLIB)
	boolean proxyTargetClass() default false;

	// 基于 代理 或 AspectJ 的通知模式,默认就是前者
	AdviceMode mode() default AdviceMode.PROXY;

	// 排序值
	int order() default Ordered.LOWEST_PRECEDENCE;

}

一些通知相关的核心属性重点是 import 了配置类 AsyncConfigurationSelector,会引入一些必要的 bean 组件 AsyncConfigurationSelector

public class AsyncConfigurationSelector extends AdviceModeimportSelector {

	// ...
	
	@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;
		}
	}

}

AsyncConfigurationSelector 是一个 importSelector(可见父类 AdviceModeimportSelector),其 selectimports 方法会返回对应的 bean 组件类名,最终被注册进容器通常情况下,注册的配置类为 ProxyAsyncConfiguration ProxyAsyncConfiguration AbstractAsyncConfiguration

@Configuration(proxyBeanMethods = false)
public abstract class AbstractAsyncConfiguration implements importAware {

	// ...
	
	// 获取容器中的 AsyncConfigurer
	@Autowired
	void setConfigurers(ObjectProvider configurers) {
		Supplier configurer = SingletonSupplier.of(() -> {
			List candidates = configurers.stream().collect(Collectors.toList());
			if (CollectionUtils.isEmpty(candidates)) {
				return null;
			}
			if (candidates.size() > 1) {
				throw new IllegalStateException("only one AsyncConfigurer may exist");
			}
			return candidates.get(0);
		});

		// 如果有且仅有一个 AsyncConfigurer 实例,则从中解析 executor 和 exceptionHandler
		this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
		this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
	}

 	// ...

}

父类 AbstractAsyncConfiguration 是 Spring Async 配置基类,此处允许用户提供一个唯一的 AsyncConfigurer 配置类,从中获取对应的 executor 和 exceptionHandler如果不提供,则最终执行器的解析如之前所述会默认从容器中获取容器中唯一 type = TaskExecutor 或 name = taskExecutor 的 bean 实例,否则默认 SimpleAsyncTaskExecutor不能提供多个 AsyncConfigurer,否则报错 ProxyAsyncConfiguration

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {

	@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
		Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
		
		// 注册一个 AsyncAnnotationBeanPostProcessor
		AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
		bpp.configure(this.executor, this.exceptionHandler);
		Class customAsyncAnnotation = this.enableAsync.getClass("annotation");
		if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
			bpp.setAsyncAnnotationType(customAsyncAnnotation);
		}
		bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
		bpp.setOrder(this.enableAsync.getNumber("order"));
		return bpp;
	}

}

子类 ProxyAsyncConfiguration 中默认注册一个 AsyncAnnotationBeanPostProcessor关于 AsyncAnnotationBeanPostProcessor 前文已经了解,是 ProxyProcessorSupport 的一个核心分支,其下会指定一个 AsyncAnnotationAdvisor 来完成代理通知逻辑实现最终的 Spring Async 总结

至此,对 Spring Async 的使用及其实现原理总结如下:

    引入 @EnableAsync 注解,最佳实践下应该提供自定义配置类 AsyncConfigurer 来完成 执行器 的配置引入的 @EnableAsync 注解最终会基于 AsyncConfigurer 来配置默认(全局)执行器和 AsyncUncaughtExceptionHandler同时,会注册一个 AsyncAnnotationBeanPostProcessor 到容器中AsyncAnnotationBeanPostProcessor 是 ProxyProcessorSupport 的一个核心分支,其下会指定一个 AsyncAnnotationAdvisorAsyncAnnotationAdvisor 由 AnnotationAsyncExecutionInterceptor 和基于注解匹配的 Pointcut 组成AnnotationAsyncExecutionInterceptor 实现将对应的异步方法交给对应的执行器调度,同时还支持 @Async 的 value 属性指定具体执行器

上一篇:【Spring】Spring Async 的实现原理 2 - AsyncAnnotationAdvisor

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/704381.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号