保健励志美文体育育儿作文
投稿投诉
作文动态
热点娱乐
育儿情感
教程科技
体育养生
教案探索
美文旅游
财经日志
励志范文
论文时尚
保健游戏
护肤业界

Spring异步实现原理与实战分享

  前言:
  最近因为全链路压测项目需要对用户自定义线程池Bean进行适配工作,我们知道全链路压测的核心思想是对流量压测进行标记,因此我们需要给压测的流量请求进行打标,并在链路中进行传递,那么问题来了,如果项目中使用了多线程处理业务,就会造成父子线程间无法传递压测打标数据,不过可以利用阿里开源的ttl解决这个问题。
  全链路压测项目的宗旨就是不让用户感知这个项目的存在,因此我们不可能让用户去对其线程池进行改造的,我们需要主动去适配用户自定义的线程池。
  在适配过程的过程中无非就是将线程池替换成ttl去解决,可通过代理或者替换Bean的方式实现,这方面不是本文的内容,本文主要是深入Spring异步实现的原理,让大家对Spring异步编程不再陌生!
  正文:运行原理分析
  过一遍源码分析,才能知道其中的一些细节原理,这也是不可避免的过程,虽然我也不想在文章中贴过多的源码,但如果不从源码中得出原因,很可能你会知其然不知其所以然。下面就尽量跟着源码走一遍它的运行机制是怎么样的,我把我自己的理解也会尽量详细地描述出来,在这里我会将其关联的源码贴出来分析,这些源码都有其相互关联性,可能你看到后面还会回来再看一遍。注册通知器过程
  开启Spring异步编程之需要一个注解即可:EnableAsync
  Springboot中有非常多Enable的注解,其目的是显式开启某一个功能特性,这也是一个非常典型的编程模型。
  EnableAsync注解注入了一个AsyncConfigurationSelector类,这个类目的就是为了注入ProxyAsyncConfiguration自动配置类,它的父类AbstractAsyncConfiguration做了件事情:
  org。springframework。scheduling。annotation。AbstractAsyncConfigurationsetConfigurers
  我们可以实现AsyncConfigurer接口的方式去自定义一个线程池Bean,这个后面会会讲到,源码所示,这里目的是为了这个bean,并将其定义的线程池对象和异常处理对象保存到AsyncConfiguration中,用于创建AsyncAnnotationBeanPostProcessor。
  这两个对象后面源码分析会再次遇上。
  而这个配置类就是为了注册一个名为AsyncAnnotationBeanPostProcessor的bean,如其名,它是一个BeanPostProcessor处理器,它的类继承结构如下所示:
  从类继承结构可以看出,AsyncAnnotationBeanPostProcessor实现了BeanPostProcessor和BeanFactoryAware,因此AsyncAnnotationBeanPostProcessor会在setBeanFactory方法中做了Spring异步编程中最为重要的一步,创建一个针对Async注解的通知器AsyncAnnotationAdvisor(叫做切面貌似也可以),这个通知器主要用于拦截被Async注解的方法。同时,bean实例初始化过程会被AsyncAnnotationBeanPostProcessor拦截处理,处理过程会将符合条件的bean注册AsyncAnnotationAdvisor:
  org。springframework。aop。framework。AbstractAdvisingBeanPostProcessorpostProcessAfterInitialization
  创建通知器过程
  接下来我们就分析AsyncAnnotationAdvisor是如何创建的。
  AsyncAnnotationAdvisor实现了PointcutAdvisor接口,因此需要同时实现getPointcut和getAdvice方法,而这两个方法的实际内容有以上红框创建实现。
  到这里我们已经知道,Spring的异步实现原理,是利用SpringAOP切面编程实现的,通过BeanPostProcessor拦截处理符合条件的bean,并将切面织入,实现切面增强处理。
  SpringAOP编程核心概念:Advice:通知,切面的一种实现,可以完成简单的织入功能。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是执行之后执行等。切入点定义切入的位置,通知定义切入的时间;
  Pointcut:切点,切入点指切面具体织入的方法;
  Advisor:切面的另一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。
  因此我们需要创建一个切面和切入点:buildAdvice:
  buildAdvice方法可知,切面是一个AnnotationAsyncExecutionInterceptor类,该类实现了MethodInterceptor接口,其invoke方法即为拦截处理的核心源码,后面会进行详细分析。buildPointcut:
  从AsyncAnnotationAdvisor构造器中可以看出,buildPointcut方法目的就是为了创建Async注解的切入点。通知器拦截处理过程
  前面我们已经知道,拦截切面是一个AnnotationAsyncExecutionInterceptor类,我们直接定位到invoke方法一探究竟:
  org。springframework。aop。interceptor。AsyncExecutionInterceptorinvoke
  拦截处理的核心逻辑就是这么简单,也没啥好分析的,无非就是匹配方法指定的线程池,接着构建执行单元Callable,最后调用doSubmit方法执行。如何匹配线程池?
  重点在于如何匹配线程池,这也是后面实战分析的重点内容,因此我们需要在这里详细分析匹配线程池的一些策略细节。
  org。springframework。aop。interceptor。AsyncExecutionAspectSupportdetermineAsyncExecutor
  getExecutorQualifier方法目的是获取Async注解上的value值,value值即线程池Bean的名称,如果获取到的targetExecutor不是Spring类型的线程池,则使用TaskExecutorAdapter进行适配,这也是为什么我们直接创建Executor类型的线程池Spring也是支持的原因。
  从以上源码逻辑可看出如果我们使用Async注解时value值为空,Spring就会使用defaultExecutor,defaultExecutor是什么时候赋值的呢?上面内容已经有提及,在buildAdvice方法创建AnnotationAsyncExecutionInterceptor时调用了其configure方法,如下:
  org。springframework。aop。interceptor。AsyncExecutionAspectSupportconfigure
  原来当defaultExecutor和exceptionHandler是当初从ProxyAsyncConfiguration中获取用户自定义的AsyncConfigurer实现类而来的,那么如果defaultExecutor不存在怎么办?从源码可看出,defaultExecutor其实是一个SingletonSupplier类型,如果调用get方法不存在,则使用默认值,默认值为:()getDefaultExecutor(this。beanFactory);
  org。springframework。aop。interceptor。AsyncExecutionAspectSupportgetDefaultExecutor
  注意第一个红框的注释,此时Spring寻找默认的线程池Bean为指定Spring的TaskExecutor类型,并非Executor类型,如果Bean容器中没有找到TaskExecutor类型的Bean,则继续寻找默认为以下名称的Bean:publicstaticfinalStringDEFAULTTASKEXECUTORBEANNAMEtaskExecutor;
  那么如果都没有找到怎么办呢?在这个方法直接返回null了,AsyncExecutionInterceptor类覆写了这个方法:
  org。springframework。aop。interceptor。AsyncExecutionInterceptorgetDefaultExecutor
  如果没有找到,则直接创建一个SimpleAsyncTaskExecutor类作为Async注解底层使用的线程池。
  从匹配线程池源码得知,如果你创建的线程池Bean非TaskExecutor类型并且没有使用实现AsyncConfigurer接口方式创建线程池,就需要主动指定线程池Bean名称,否则Spring会使用默认策略。总结
  利用BeanPostProcessor机制在Bean初始化过程中创建一个AsyncAnnotationAdvisor切面,并且符合条件的Bean生成代理对象并将AsyncAnnotationAdvisor切面添加到代理中。
  可以看出Spring的很多功能都是围绕着SpringIOC和AOP实现的。Spring默认线程池策略分析
  有时候为了方便,我们不自定义创建线程池bean时,Spring默认会为我们提供什么样的线程池呢?
  我们先来看下结果:
  很奇怪,明明我们都没有在项目中自定义线程池Bean,按照以上源码的分析结果来看,此时Spring选择的是SimpleAsyncTaskExecutor才对,莫非是supergetDefaultExecutor方法找到了线程池Bean?
  从以上截图确实是找到了,而且类型还是ThreadPoolTaskExecutor类型的,那可以推断出Spring一定是在某个地方创建了一个ThreadPoolTaskExecutor类型的Bean。
  果然,在springbootautoconfigure2。1。3。RELEASE中,会在org。springframework。boot。autoconfigure。task。TaskExecutionAutoConfiguration中自动创建一个默认的ThreadPoolTaskExecutorbean,getDefaultExecutor方法会在容器中找到这个bean,并将其作为默认的Async注解的执行线程池。
  这里我为什么要标注版本呢?因为某些低版本的springbootautoconfigure,是没有TaskExecutionAutoConfiguration的,此时Spring就会选择SimpleAsyncTaskExecutor。
  org。springframework。boot。autoconfigure。task。TaskExecutionAutoConfiguration
  从以上源码可以看出,默认的线程池的参数还可以手动在properties中配置,这意味着不需要主动创建线程池的情况下,也可以通过properties配置文件更改线程池相关参数。创建线程池Bean的几种方式
  1、直接创建一个Bean的方式,这貌似是最多人使用的方式,可以创建多个线程池Bean,使用时指定线程池Bean名称:Bean(myTaskExecutor1)publicExecutorgetThreadPoolTaskExecutor1(){finalThreadPoolTaskExecutorexecutornewThreadPoolTaskExecutor();set。。。returnexecutor;}Bean(myTaskExecutor2)publicExecutorgetThreadPoolTaskExecutor2(){finalThreadPoolExecutorexecutornewThreadPoolExecutor();set。。。returnexecutor;}
  2、实现AsyncConfigurer接口方式:ComponentpublicclassAsyncConfigurerTestimplementsAsyncConfigurer{privatestaticfinalLoggerLOGGERLoggerFactory。getLogger(AsyncConfigurerTest。class);OverridepublicExecutorgetAsyncExecutor(){ThreadPoolTaskExecutorexecutornewThreadPoolTaskExecutor();set。。。returnexecutor;}OverridepublicAsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler(){return(ex,method,params){LOGGER。info(Exceptionmessage:{},ex。getMessage(),ex);LOGGER。info(Methodname:{},method。getName());for(Objectparam:params){LOGGER。info(Parametervalue:{},param);}};}}
  这种方式可以方便定义异常处理的逻辑,不过从源码分析可以看出,项目中只能存在一个AsyncConfigurer的配置,意味着我们只能通过AsyncConfigurer配置一个自定义的线程池Bean。
  3、利用springbootautoconfigure在properties配置线程池参数:
  前面讲到了Spring默认线程池策略,这里利用springbootautoconfigure默认创建一个ThreadPoolTaskExecutor,通过properties自定义线程池相关参数。
  这个方式的缺点就是类型固定为ThreadPoolTaskExecutor,且只能有一个线程池。总结了很多有关于java面试的资料,希望能够帮助正在学习java的小伙伴。由于资料过多不便发表文章,创作不易,望小伙伴们能够给我一些动力继续创建更好的java类学习资料文章,
  请多多支持和关注小作,别忘了点赞评论转发。右上角私信我回复【03】即可领取免费学习资料谢谢啦!
  作者:张乘辉
  原文出处:https:mp。weixin。qq。comsmNDwZfPK90RoGmJGHCjKrw

关于读书名言比喻读书名言分享1、读万卷书,行万里路。mdash;mdash;刘彝2、黑发不知勤学早,白首方悔读书迟。mdash;mdash;颜真卿3、书卷多情似故人,晨昏忧乐……3年级做一个有道德的人征文导语:在这个社会上,要做一个有道德的人。下面是小编整理的一些关于做一个有道德的人征文,请大家认真阅读!【做一个有道德的人征文1】在这个社会上,要做一个有道德的人。l……积攒时光作文时光匆忙,日子一天天过去,转过了表盘一圈一圈,转过了四季流转轮换。新年的脚步悄悄到来。多少人都像拧紧了发条的傀儡娃娃,匆忙奔走在大街小巷里。人来人往,岁月沧桑。我们在命运……睡眠是最好的补药,睡不着的人,要多吃这三种食物一天当中,我们有三分之一的时间是在睡眠中度过的,当我们在睡觉的时候,身体内的各器官进入休息状态,所以我们睡得越好,各器官休息得也就更充分,自然我们的身体也就更好了。但是现代人由……猴岛人类把409只猴子困在这里,研究了80多年在地球另一边,离波多黎各东岸不远的地方,有一座15。2公顷的无人小岛,凯佑圣地亚哥岛(CayoSantiago)。今天,在这个南北长600米,东西长400米的小小岛屿上,……做自己为话题的作文(通用8篇)大家一定都接触过作文吧,尤其是在作文中占有重要地位的话题作文,话题作文是提供了个话题,但对取材范围和表达方式不予限制的作文形式。那么你有了解过话题作文吗?以下是小编为大家整理的……小鸭子过马路小学作文有一天,一群憨态可掬的小鸭子漫步在温哥华街头。鸭妈妈带着六只小鸭子穿梭在城市中,左看看,右看看,对一切东西都感觉很新鲜。它们是怎么来的呢?原来,鸭妈妈和小鸭子在农场生活得很无聊……美丽的燕鱼小学作文星期天,我到小红家去玩。她家养了许多燕鱼,有黑白燕,金头燕,墨燕我站在鱼缸前,仔细地观察每一条燕鱼。从侧面看,燕鱼很像天空中飞翔的燕子,头小小的,身子宽宽的,尾巴长长的,……身高焦虑9岁女孩为打性抑制针,大半年花了近十万专家患矮小症的钱江晚报小时新闻记者刘俏言CFP供图打还是不打?张凤(化名)一家曾陷入长久的纠结。打,有副作用,不打,会影响孩子的身高。这是两难的选择。在纠结背后,更多的则是……小学生作文勤奋的一个人作文一:勤奋的一个人你要问我给我印象最深刻的人是谁?我会毫不犹豫地告诉你是我的好友mdash;mdash;王柏。他有一头乌黑的短发,炯炯有神的大眼睛下长着高鼻梁,说起话来……任泽平中国居民户均资产高达134。4万,主要表现在房产上这些年房地产市场的高速发展,让我们看到了房子的巨大价值,不仅仅只有居住属性在里面,也成为了现在很多人理财的重要渠道。在几亿人口进城的巨大需求之下,房子的增值属性表现得更为明显,……徐云骑行西藏半年,冷暖自知,苦乐自度,愿骑行者们一路顺风大概是五一期间,偶然间看到徐云流浪中国的视频,看了之后感觉确实不错。真的是不看不知道,一看刹不住。所以就一直看了下去了,追剧的感觉满满。每天最期待的就是看徐云骑行视频,然……
女足世界杯分组10月22日进行,扩军到32支球队中国队已获晋北京时间5月13日,FIFA在官网宣布,2023年女足世界杯的分组抽签仪式将在今年的10月22日举行。中国女足此前已经凭借亚洲杯夺冠,获得了晋级名额,本届女足世界杯扩军到32支……女足的范大将军,1米66却擅长头球,本可绝杀美国却遭遇冤案提起中国足坛的范大将军,相信绝大多数球迷的第一反应,都是范志毅这个霸气绝伦却又不失幽默的男足代表性人物。诚然,范志毅无论江湖地位还是行事风格,都绝对配得上范大将军的偌大名……21!王珊珊率队6轮不败,施压陈婉婷,女超劲旅7战6败跌至倒问:如何才能每天都能收到这样的体育资讯?答:只需点击右上角关注即可。北京时间5月11日,女超联赛第九轮比赛打响。下午14点15分,北京女足对阵广东梅州客家女足。赛前……铿锵玫瑰孙雯带伤书写女足辉煌,与华人丈夫在婚姻中有遗憾点击关注,每天都有名人故事感动您!孙雯孙雯是享誉海内外的著名女足运动员,堪称铿锵玫瑰的代表人物。她曾担任中国女足队长,与队友们夺得1996年亚特兰大奥运会亚军……31!中国女足小将无缘欧冠,王霜在大巴黎的纪录暂时无人能破又是一场酣畅淋漓的大胜!在苏超女足第25轮比赛,中国女足小将沈梦雨所在的凯尔特人女足,以31的比分大胜斯巴顿斯女足。本场比赛大胜之后,凯尔特人女足也在联赛豪取4连胜。排名牢牢占……同样是做核酸,把葛优冯巩李明启和万梓良放一起,差距瞬间出来了一场突如其来的疫情,让全国多个城市被迫按下了暂停键,或慢速键。本是高高在上的明星们,和普通人一样被困在了各自的小区,他们每天的生活就是吃饭宅家做核酸。然而,做核酸本是一件……谢晖刚接手大连队,就让球队大佬被迫离队,如今已沦落业余联赛日前,根据德转市场显示43岁的周挺已经加盟大连金石湾。金石湾是一支中冠球队,周挺来到球队之后,只要能正常发挥出水平,就可以锁定核心主力。周挺在2020赛季已经宣布退役,所以球迷……大爆冷!女单前4号种子全军覆没,世界亚军惨败,日本3人进半决乒乓球WTT美国韦斯切斯特赛已进入尾声,北京时间5月15日,女子单打的四强名单正式出炉,让人感到非常意外的是,前4号种子已经全军覆没,世界亚军郑怡静等人惨遭淘汰,而日本队竟然有……放弃承办中国亚洲杯,国足种子资格被取消,分组或成二三档球队最近一段时间国内体坛发生了太多大事,汕头亚青会、成都大运会、杭州亚运会三大亚洲综合性运会取消或者延期,如今作为中国足坛能够举办的最大型足球赛事,2023中国亚洲杯也宣布取消。不……偰李永炜社媒透露已经抵达美国将代表皇家盐湖城学院征战高四赛季北京时间5月15日,中国篮球小将偰李永炜在社媒宣布,他已经接受美国美国皇家盐湖城学院邀请,将代表该校征战高四赛季。偰李永炜今日在社媒宣布,他已经顺利抵达美国,未来将代表美……被红楼梦写中人生的演员2人英年早逝,晴雯为夫还债1100万1987年,历经四年时间打磨的电视剧《红楼梦》于央视开播,播出后便获得来自各界的众多好评。一晃35周年过去,该剧重播了一千多次,被誉为中国电视史上的绝妙篇章和不可逾越的经……湖南文旅数据早知道省内文旅要闻TOP31。2022中华茶祖节潇湘邵阳红湖南生态旅游节暨第三届舜皇山野茶节将举行5月15日,2022中华茶祖节潇湘邵阳红2022湖南省生态旅游节暨第三届……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网