范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

你必须知道的SpringAsync的一些坑

  前言
  大家都知道 用@Trancational,@Async,@Retryable 等注解时,需要用代理调用才生效,用this调用是不生效的。
  大多数情况,是由另外的类发起调用,这是没有问题的。
  少数情况下,存在本类调用本类方法,这种情况下要做到注解生效,该怎么办呢?
  常见的解决方法有以下几种: 从applicationContext种获取bean 自己注入自己 AopContext.currentProxy() 需要使用 @EnableAspectJAutoProxy(exposeProxy = true)@Async注解的原理
  @EnableAsync注解上标注了@Import(AsyncConfigurationSelector.class),AsyncConfigurationSelector在默认情况下,会选择出来ProxyAsyncConfiguration类进行导入,即把ProxyAsyncConfiguration类作为@Configuration类配置到ApplicationContext @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() {       Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");       AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();       Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");       if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {          bpp.setAsyncAnnotationType(customAsyncAnnotation);       }       if (this.executor != null) {          bpp.setExecutor(this.executor);       }       if (this.exceptionHandler != null) {          bpp.setExceptionHandler(this.exceptionHandler);       }       bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));       bpp.setOrder(this.enableAsync.getNumber("order"));       return bpp;    }   }
  这段代码的作用是把AsyncAnnotationBeanPostProcessor作为Bean注册到Context中。
  我们看下这个Async相关的BPP做了什么操作: // 潜质处理不做任何动作,可保证在调用bean的init之前,bean本身没有任何变化。 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) {     return bean; }   @Override public Object postProcessAfterInitialization(Object bean, String beanName) {     // 如果是AOP相关的基础组件bean,如ProxyProcessorSupport类及其子类,则直接返回。     if (bean instanceof AopInfrastructureBean) {         // Ignore AOP infrastructure such as scoped proxies.         return bean;     }       if (bean instanceof Advised) {         // 如果已经是Advised的,即已经是被动态代理的实例,则直接添加advisor。         Advised advised = (Advised) bean;         if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {             // 如果没有被frozen(即冷冻,不再做改动的动态代理实例)且是Eligbile(合适的),则把其添加到advisor中。根据配置决定插入位置。             // Add our local Advisor to the existing proxy"s Advisor chain...             if (this.beforeExistingAdvisors) {                 advised.addAdvisor(0, this.advisor);             }             else {                 advised.addAdvisor(this.advisor);             }             return bean;         }     }       if (isEligible(bean, beanName)) {         // 如果是Eligible合适的,且还不是被代理的类,则创建一个代理类的实例并返回。         ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);         if (!proxyFactory.isProxyTargetClass()) {             evaluateProxyInterfaces(bean.getClass(), proxyFactory);         }         proxyFactory.addAdvisor(this.advisor);         customizeProxyFactory(proxyFactory);         return proxyFactory.getProxy(getProxyClassLoader());     }       // No async proxy needed.     return bean; } // 准备ProxyFactory对象 protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {     ProxyFactory proxyFactory = new ProxyFactory();     proxyFactory.copyFrom(this);     // 设置被代理的bean为target,这个bean是真实的bean。     proxyFactory.setTarget(bean);     return proxyFactory; }
  Spring在对一个类进行AOP代理后,会为此类加上Advised接口,返回的动态代理对象都会带上Advised接口修饰,那么第一段逻辑判断bean instanceof Advised的目的就是判断是否已经是被动态代理的类,如果是,则为其添加一个Advisor增强器。
  如果不是动态代理的对象,因为@Async要为方法增加代理,并转换为异步执行,故需要把原始bean转换为被AOP动态代理的bean。 快问快答
  问题1:@Async注解在使用第三种方法AopContext.currentProxy() 调用本类方法能生效吗?
  答案:不能生效
  原因:EnableAspectJAutoProxy(exposeProxy=true)用的是  AnnotationAwareAspectJAutoProxyCreator 这个bbp 所以EnableAspectJAutoProxy(exposeProxy=true) 这个注解的 exposeProxy=true 只针对由这个bbp创建的代理类生效,而Async注解的代理是由自己创建的
  问题2:@Transactional注解在使用第三种方法AopContext.currentProxy() 调用本类方法能生效吗?
  答案:可以生效
  原因:Transactional注解种的bbp是 InfrastructureAdvisorAutoProxyCreator,而 EnableAspectJAutoProxy 会把 InfrastructureAdvisorAutoProxyCreator 替换成 AnnotationAwareAspectJAutoProxyCreator。代码在  AopConfigUtils 种的 registerOrEscalateApcAsRequired  方法 /**  * Stores the auto proxy creator classes in escalation order.  */ private static final List> APC_PRIORITY_LIST = new ArrayList>();   /**  * Setup the escalation list.  */ static {    APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);    APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);    APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class); }        private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {       BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);       if (!cls.getName().equals(apcDefinition.getBeanClassName())) {          int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());          int requiredPriority = findPriorityForClass(cls);          if (currentPriority < requiredPriority) {             apcDefinition.setBeanClassName(cls.getName());          }       }       return null;    }    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);    beanDefinition.setSource(source);    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);    return beanDefinition; }
  所以 Transactional注解是能享受到 EnableAspectJAutoProxy 注解的福利的
  问题3:@Transactional @Async 一起用的话 调用本类方法能生效吗?
  答案:可以生效
  原因:AsyncAnnotationBeanPostProcessor 优先级是最低 而AnnotationAwareAspectJAutoProxyCreator 优先级是最高,所以Async注解可以不用自己创建代理,而复用AnnotationAwareAspectJAutoProxy创建的代理。
  引申:为什么引入spring cloud starter sleuth包后 @Async注解就能用AopContext.currentProxy
  原因:sleuth包中定义了 @Async的切面

MySQLPGOracleSqlServer达梦数据库扫描表字段元数据SQL1MySQL表查询SELECTASTABLESCHEMA,TABLENAME,TABLECOMMENTFROMinformationschema。TABLESWHERETABLES欧盟USBTypeC提案正式通过,iPhone淘汰Lightning接口倒数开始欧盟近年打算统一USBTypeC接孔,近日欧洲议会内部市场与消费者保护委员会(IMCPC)进行投票,以43高票通过赞成(2票反对),同意电子产品全统一改为USBTypeC标准,市场Hadoop生态体系学习笔记(一)HDFS分布式文件系统理论基础本文仅仅只是个人学习的笔记,不代表一定就是对的,仅供参考。分布式计算的思想为分治,由于信息技术的发展,数据的量级变得越来越大,但是一台单机处理数据的能力有限。比如现在有这样的一个需python有什么用?能做哪些有趣的事情?现在越来越多的人开始学习python语言,好像不会点编程都不好意思说是混互联网的那python到底是干嘛的呢?有哪些具体用途呢?下面我就为你简单罗列一下1。网站开发网站开发即Web马斯克440亿美元收购推特(TWTR。US)交易再遇挑战佛罗里达州养老基金正在起诉美国佛罗里达州的一个养老基金正在对特斯拉(TSLA。US)CEO马斯克440亿美元的推特(TWTR。US)收购案提出法律挑战,称他与该社交媒体平台其他股东的财务安排应阻止该交易在2全球13台根服务器10台在美国,如果美国关闭服务,对哪国影响最大互联网连接万物,把整个世界变成地球村,而维持互联网正常运转的通信中枢,就是13个根服务器,这其中有10个位于美国。作为全球互联网的中枢系统,根服务器的重要性不言而喻,就美国蛮横不讲美国德州仪器裁撤中国区MCU团队,并将原MCU生产线迁往印度德州仪器是美国德克萨斯州一家半导体跨国公司,以开发制造销售半导体和计算机技术闻名于世,并且在手机处理器行业内,可以说是元老级的芯片厂商,但随着高通芯片火热,德州仪器才淡出我们视野。港股收评恒指跌3。81恒生科技指数跌5。23腾讯跌超4,京东阿里巴巴跌超6受隔夜美股大跌影响,港股今日呈单边下跌行情,热门板块全部下挫,市场整体情绪表现较差。截止收盘,恒指跌3。81险守20000点,恒生国企指数跌4。33,恒生科技指数跌5。23。盘面上追踪八岁孩子游戏充值八千余元家长已收到退款7300余元5月5日上午,王先生告诉华商报记者,孩子打游戏充值的钱终于退回来了,广东天宸网络科技有限公司最终扣了几百元钱,说是服务费,最终退回7300余元。王先生表示可以接受,同时也表示,他和联想控股股份有限公司和现在的联想电脑有关系吗?目前联想控股是联想集团的母公司,属于专业资本运营集团,柳传志等联想高层的持股高达30。8,是联想第一大股东,中科院占29股权,已经退居第二位了。联想集团主营电脑业务,目前联想控股仅网宿科技股份有限公司2021年年度报告摘要300017网宿科技成立于2000年1月,致力于成为全球领先的IT基础平台服务提供商。通过提供计算存储网络及安全等新一代信息技术服务,助力互联网客户政府及企业客户获得快速稳定安全的IT能力和用
买书的六大网站有哪些?买书有六大网站可以选择。买新书京东,当当,淘宝,天猫。买旧书孔夫子旧书网,多抓鱼,闲鱼转转。首先声明一下我说的这些不是广告,只是陈述一下我买书的经历经验。首先说一下京东。京东自营的iOS15。0Beta5发布,新增22项改动前言距离上次更新刚好两周。苹果准时地推送了iOS15Beta5。一晃已经到第五版了。作为对比,iOS14一共有8个Beta版本。看样子怎么也算是正式进入后半段了。而回到固件上来。这雷军向小米用户发放1999红包,涉及18万用户一个品牌回馈用户的方式有很多种,米面粮油小礼盒比比皆是,能够直接发钱的例子可是少之又少。近日小米集团CEO雷军因回馈用户的方式过于实在再上热搜大手一挥,每人送1999红包。(图源网新购电脑,选AMD板U套装就对了上周隶属于锐龙5000G系列的锐龙75700G和锐龙55600G正式上市,标志着消费市场上的锐龙APU在时隔3年之后终于迎来了换代。对于饱受缺卡困扰的玩家来说,锐龙75700G和锐物联网卡到底能不能用在手机上?物联网卡能不能在手机上使用,有很多人在问这个问题,有人说不能在手机上使用,有人说可以在手机上使用了,物联网卡到底能不能在手机上使用呢?,咱们今天就聊聊这个话题。那什么是物联网卡呢?正点原子I。MX6U嵌入式Qt开发指南第十一章网络编程3今日头条西瓜视频抖音短视频同名正点原子原子哥今日头条西瓜视频抖音短视频账号正点原子原子哥感谢各位的关注和支持,你们的关注和支持是正点原子无限前进的动力。第十一章网络编程由于本章内容监控系统选型必知必会!ZabbixPrometheus等(内含自学教程)没有衡量,就没有管理。彼得德鲁克Linux系统在企业中的应用程度已经非常广泛,人们听到过太多关于Docker和Kubernetes的消息,以至于忘记了监控和日志记录也是同样重要的任开学了,要换个本儿吗?笔记本电脑超强科普购买攻略疫情以来全民进入了zoomuni时代这时候一台能带的动的电脑是多么重要!你要知道不同专业对电脑可都有不一样的需求苹果虽然好但却不支持部分专业软件轻薄本虽然便捷,但做剪辑却不是最优选老牌商务机迈进亿时代摩托罗拉edgespro全面评测掐指算来,年龄最大的90后已过而立之年,绝大多数90后也已成长为职场上的中坚力量。作为经常从事商业活动的新时代年轻商务人士,一部匹配自身气质的高素质智能手机不可或缺。不过放眼国内智麒麟芯回来了?华为新机发布,搭载中芯国际14nm工艺芯片大家都知道,本来华为手机使用自己研制的麒麟芯片,前景一片大好。但是,美国修改了规则,使得华为不得不出售了荣耀手机业务,随着形势越来越严峻,华为的Mate40和P50系列都不得不采用有效提问200以内的耳机都是垃圾近日,微博上出现超话怎么有效提问得到自己想要的安利推荐呢?网友有妙招一时之间,这种按头安利提问屡试不爽,被称之为有效提问。这些高智商操作令人拍案叫绝,哈哈哈提到耳机,他的演变路程也