spring 的异步处理
1.先解析几个类的用法
1.1 java.lang.annotation.Annotation
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
String color() default "red";
}
javac编译之后,interface MyAnnotation extends java.lang.annotation.Annotation 这段表示我自定义的MyAnnotation注解最终是被编译成一个继承java.lang.annotation.Annotation的接口
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync { /**
* 表示可以在这里指定注解类,开启异步操作和@Async同样效果*/
Class<? extends Annotation> annotation() default Annotation.class;
具体原理可以查看:
ProxyAsyncConfiguration
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
bpp.configure(this.executor, this.exceptionHandler);
Class<? extends Annotation> 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.<Integer>getNumber("order"));
return bpp;
}
AsyncAnnotationBeanPostProcessor
@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
public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) {
Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null");
Set<Class<? extends Annotation>> asyncAnnotationTypes = new HashSet<>();
asyncAnnotationTypes.add(asyncAnnotationType);
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
protected Pointcut buildPointcut(Set<Class<? extends Annotation>> 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);
}
else {
result.union(cpc);
}
result = result.union(mpc);
}
return (result != null ? result : Pointcut.TRUE);
}
1.2.@Role
@see BeanDefinition#ROLE_APPLICATION 通常为用户自定义的bean
* @see BeanDefinition#ROLE_INFRASTRUCTURE 处理bean注册时,内部工作的 例如:生成代理类的配置
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration { @Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
* @see BeanDefinition#ROLE_SUPPORT 支持大配置中的一部分
未找到使用场景
2.配置方法
2.1 @EnableAsync (ProxyAsyncConfiguration)
2.2TaskExecutionAutoConfiguration
3.主要处理类
3.1 AnnotationAsyncExecutionInterceptor
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);
}
else if (ListenableFuture.class.isAssignableFrom(returnType)) {
return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
}
else if (Future.class.isAssignableFrom(returnType)) {
return executor.submit(task);
}
else {
executor.submit(task);
return null;
}
}
3.2 获取executor的过程
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());
@Nullable
protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
AsyncTaskExecutor executor = this.executors.get(method);
if (executor == null) {
Executor targetExecutor;
String qualifier = getExecutorQualifier(method);
if (StringUtils.hasLength(qualifier)) {
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
}
else {
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 Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
//super.getDefaultExecutor(beanFactory);
return beanFactory.getBean(TaskExecutor.class);
常用的Executor的几个种类,和转换
public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport
implements AsyncListenableTaskExecutor, SchedulingTaskExecutor { public class SimpleAsyncTaskExecutor extends CustomizableThreadCreator
implements AsyncListenableTaskExecutor, Serializable { Executor targetExecutor;
new TaskExecutorAdapter(targetExecutor)
注意 TaskDecorator 应用场景1.thread中 traceId往子线程中传递可以在在这个任务修饰器中完成
class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
Map<String, String> contextMap = MDC.getCopyOfContextMap(); Runnable runnable1 = new Runnable() {
@Override
public void run() {
if (contextMap != null) {
MDC.setContextMap(contextMap);
}
runnable.run();
}
};
return runnable1;
}
}
@Slf4j
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer { @Bean
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("async-pool-");
executor.setTaskDecorator(new MdcTaskDecorator());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
} @Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, params) -> {
log.error("异步任务异常:方法:{} 参数:{}", method.getName(), JSON.toJSONString(params));
log.error(throwable.getMessage(), throwable);
};
}
}
spring 的异步处理的更多相关文章
- Spring mvc异步处理
基于Servlet3.0的异步处理,springmvc的异步处理 控制器返回callable, spring mvc异步处理,将callable提交到TaskExecutor 使用一个隔离线程进行执 ...
- Spring MVC 异步处理请求,提高程序性能
原文:http://blog.csdn.net/he90227/article/details/52262163 什么是异步模式 如何在Spring MVC中使用异步提高性能? 一个普通 Servle ...
- Spring Boot系列二 Spring @Async异步线程池用法总结
1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...
- spring启动异步线程
大纲: spring启动异步线程 spring配置线程池 一.spring启动异步线程 spring启动异步线程方法就是在方法上加上注解@Async,然后启动类或配置类上加上注解@EnableAsyn ...
- Spring中异步注解@Async的使用、原理及使用时可能导致的问题
前言 其实最近都在研究事务相关的内容,之所以写这么一篇文章是因为前面写了一篇关于循环依赖的文章: <面试必杀技,讲一讲Spring中的循环依赖> 然后,很多同学碰到了下面这个问题,添加了S ...
- Spring DeferredResult 异步请求
Spring DeferredResult 异步请求 一.背景 二.分析 三.实现要求 四.后端代码实现 五.运行结果 1.超时操作 2.正常操作 六.DeferredResult运行原理 六.注意事 ...
- 基于Spring的异步系统实现方案
一般的实现方案 发送异步消息所使用的工具类: import java.util.Date; import javax.jms.Destination; import javax.jms.JMSExce ...
- Spring @EventListener 异步中使用condition的问题
@EventListener是spring在4.2+推出的更好的使用spring事件架构的方式,并且异步方式也很好设定 但是在spring4.2.7版本上使用eventlistener的conditi ...
- 深入理解Spring的异步机制
一.Spring中实现异步执行 在这里我先以事件的机制举例,注意默认情况下事件的发布与监听都是同步执行的.那么我们来看一看基于异步事件的例子该怎么写 首先还是定义事件: package com.bdq ...
- Spring MVC 异步测试
从spring3.2开始,支持servlet3的异步请求,这对于处理耗时的请求如缓慢的数据库查询是非常有好处的,不至于很快的耗光servlet的线程池,影响可扩展性. 让我们先来了解一下servlet ...
随机推荐
- yii2 环境切换(开发,正式)
方式一,在web中index修改 开发环境配置 web目录index.php defined('YII_DEBUG') or define('YII_DEBUG', true); defined('Y ...
- wx: wx.showModal 回调函数中调用自定义方法
一.在回调函数中调用自定义方法: 回调函数中不能直接使用this,需要在外面定义 var that = this 然后 that.自定义的方法.如下: //删除 onDelete: function ...
- Wannafly Camp 2020 Day 5A Alternative Accounts
There are n different accounts on the website, and some of them competed in the recent k contests. H ...
- Winform form窗体已弹出框的形式出现并回传值
From2(弹出框)回传数据到From1 Form1(数据接收form): public string Sstr; private void button1_Click(object sender, ...
- linux - 查看 python 版本
命令 python -V 结果
- Docker学习一篇就够了
Docker 1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像 ...
- 有一个树形结构,实现一个方法getKeys(data,str),获取字符串str在data中的所有上级节点的名称
有一个树形结构,实现一个方法getKeys(data,str);获取字符串str在data中的所有上级节点的名称,例如: getKeys(data,'str1') 返回 ‘key1' getKeys( ...
- SpringBoot--自动配置原理-4个注解
一.自动配置原理 四个元注解:修饰注解的注解 @Target(ElementType.TYPE) 这个注解用在那个位置上,可以使用在类上,方法上,成员变量上 @Retention(RetentionP ...
- numpy基础知识练习
# 1.导入numpy模块 # 2.创建一个大小为10的空向量 # 3.创建一个大小为10的空向量,但是第五个值为1 # 4.创建一个10-49的ndarray数组 # 5.创建一个3x3的矩阵,其值 ...
- Motif
Motif discovery is in loose terms the problem of finding interesting patterns in sequences. motif: i ...