网站首页 > 精选教程 正文
对于Spring的封装能力,大家应该是不陌生的,因此对于很多读者来讲,学会了它的使用,并不会去研究其底层的实现。例如@Async 注解,一般人可能只是注意到它是一个注解,并且在方法或者类上添加上整个注解之后,Spring会将对应的方法或者类中的所有方法都放到一个单独的线程池中去执行,通过这种方式来实现异步执行操作。但是对于@Async到底是如何运行的却不得而知,这篇文章就来跟大家一起学习其原理。
@Async
首先,需要只知道这个注解是用来标注开启异步执行操作的注解。对于这个注解本身来讲,除了依赖于Java底层的支持,还依赖了一些Spring相关的内容。通过反射的方式拦截到了标注有该注解的类,然后通过AOP来进行切面的拦截。进行切面拦击之后,就需要去实现异步方法的执行。带着这个思路我们来分析一下@Async 的原理。
如何开启异步操作呢?
在Spring中通过@EnableAsync注解来开启异步执行方法的操作。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
Class<? extends Annotation> annotation() default Annotation.class;
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
从代码中可以看到在@EnableAsync 中Import导入了一个AsyncConfigurationSelector ,这种引入也是Spring提供的引入第三方的依赖的方式。通过类名可以知道引入的是一个异步执行配置的选择器。这个默认选择器就是ProxyAsyncConfiguration
在这个类中有如下的方法,注入了AsyncAnnotationBeanPostProcessor处理器。从名称上来看就是用来处理@Async 注解的处理器。
在这个处理器中存在一个AnnotationAsyncExecutionInterceptor的拦截器,根据我们上面的分析可以知道,AOP的最外层是代理类,然后进行切面。通过Advisor创建切面。这些操作都是在AsyncAnnotationBeanPostProcessor,中来完成,如下图所示
并且在AsyncAnnotationAdvisor中创建了advice和pointcut,并且在拦截器操作中就是对advice的处理。
完成这些操作之后,关于@EnableAsync注解的作用就算完成了。它主要的操作就是利用AOP技术创建好一个切面,这个切面上所有的操作都是关于@Async的操作。
具体实现原理
在上面的介绍中,我们知道了@EnableAsync 的生效是通过AOP来实现的。但是在实现了AOP操作之后,就需要将异步操作放入到一个异步的线程池中去执行。下面我们就要去看看执行操作的线程池是在哪一步进行创建的。
在前面的分析中介绍了一个AnnotationAsyncExecutionInterceptor 拦截器类,需要创建线程池的操作就是在这个拦截器中完成的
在其父类AsyncExecutionAspectSupport中完成了对执行线程池的创建。
并且通过getDefaultExecutor 方法来获取到Spring容器中对应的执行的线程池Bean。当然在没有进行配置的情况下,默认使用的是SimpleAsyncTaskExecutor线程池。
提交执行任务执行
基于上面的分析,我们这回到,当方法被@Async注解的时候,也就是会被AnnotationAsyncExecutionInterceptor拦截器所拦截,并且通过代码分析我们找到了相关的拦截处理机制。在其父类AsyncExecutionInterceptor 中,对提交的任务进行验证分析处理。
其中determineAsyncExecutor 中获取到的就是执行的executor与具体方法对象绑定的关系,并且对于每个添加了@Async的方法来讲都会有一个独立的executor,然后调用doSubmit方法执行,并且根据对应的returnType对返回值进行处理。
自定义线程池
在上面的分析中,我们提到了可以通过配置的方式来自定义执行线程池。在SpringBoot中提供了一个AsyncConfigurer 接口来让开发人员自定义实现的线程池。可以通过继承AsyncConfigurerSupport类并且实现其中的方法来实现。需要注意的是,AsyncConfigurer在每个项目中只能有一个实现Bean实例。如果出现多个,则会抛出异常。
总结
上面我们介绍了关于@Async的相关执行原理,从整个的分析来看,基本上行基于Spring的一些优秀的实现项目都是离不开Spring的核心IOC和AOP操作。当然通过代码分析只是掌握其运行原理的一种途径,有兴趣的读者也可以利用Spring框架提供的一些便携操作来完成更加高级的实现。
- 上一篇: Java中异步复用io
- 下一篇: WebService的发布与调用
猜你喜欢
- 2024-11-19 Java 并发编程 11 - 异步执行框架 Executor
- 2024-11-19 Java中异步复用io
- 2024-11-19 JAVA异步方法笔记
- 2024-11-19 面试官:Redis分布式锁超时了,任务还没执行完怎么办?
- 2024-11-19 万能通用的异步实战方案,设计多线程,mq
- 2024-11-19 Java客户端Jedis 对Redis的几种调用方式包括事务、管道、分布式
- 2024-11-19 Dubbo 2.7新特性之异步化改造
- 2024-11-19 新手也能看懂的 SpringBoot 异步编程指南
- 2024-11-19 SpringBoot 异步编程
- 2024-11-19 C# 同步方法怎么调用异步方法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)