Async注解详解-Async的作用以及原理

文章目录

  • 起因
  • @Async作用
  • 原理
    • @EnableAsync
    • AsyncAnnotationBeanPostProcessor

起因

作为一个菜鸟,总是会遇到各种匪夷所思的bug。今天,不出意外的话今天我又遇到了意外…bug…

我在调用同事的一个方法时,莫名奇妙的报了空指针,当前请求执行了一部分后,上下文中的用户信息居然丢失了!?

在这里插入图片描述
可是我明明是登录状态,怎么会?于是我进入同事写的方法,看到了一个注解:@Async,这个没见过,所以我推测问题就出自这里。看来又该学习了。

@Async作用

其注释如下:

Annotation that marks a method as a candidate for asynchronous execution. Can also be used at the type level, in which case all of the type’s methods are considered as asynchronous. Note, however, that @Async is not supported on methods declared within a @Configuration class.

翻译:

将方法标记为异步执行的候选方法的注释。也可以在类型级别使用,在这种情况下,类型的所有方法都被视为异步的。但是,请注意,在@Configuration类中声明的方法上不支持@Async。

看的出来,这个注解可以用在类上,也可用在方法上。目的就是为了让调用的方法异步执行。

原理

注:以下对springboot的Bean加载过程有一定了解的话更容易理解。

@EnableAsync

在启动类上有@EnableAsync注解,很明显是异步注解的开关注解。进入该注解:

在这里插入图片描述
这里有两个注意的位置:

  • @Import(AsyncConfigurationSelector.class)
  • AdviceMode mode() default AdviceMode.PROXY

这里导入了类 AsyncConfigurationSelector,进入该类:

在这里插入图片描述
这里的方法selectImports()在父类中调用(注:selectImports(AnnotationMetadata importingClassMetadata)是在springboot启动过程中执行bean后置处理器时所最终调用):
在这里插入图片描述
可以看到这里获取了注解@EnableAsync中的mode属性,默认是PROXY。因此在方法selectImports()中返回了ProxyAsyncConfiguration并注入容器中:

在这里插入图片描述
进入配置类ProxyAsyncConfiguration:
在这里插入图片描述
这里配置了线程池以及异常处理器。

AsyncAnnotationBeanPostProcessor

对于BeanPostProcessor相信大家不会太陌生,按照我粗浅的理解,BeanPostProcessor是Spring框架中的一个接口,在SpingBoot启动过程中,用于在Bean实例化和初始化的过程中对Bean进行后置处理。它提供了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization

postProcessBeforeInitialization方法在Bean的初始化之前被调用,可以对Bean进行一些预处理操作。例如,可以修改Bean的属性值或者进行一些必要的校验。

postProcessAfterInitialization方法在Bean的初始化之后被调用,可以对Bean进行一些后处理操作。例如,可以对Bean进行代理或者添加一些额外的功能。

继续回到类AsyncAnnotationBeanPostProcessor,在其最下方的setBeanFactory方法中,创建了一个切面对象并赋给AsyncAnnotationBeanPostProcessor对象。
在这里插入图片描述
进入类AsyncAnnotationAdvisor中,并查看构造方法,发现它专为注解Async构造了切面(advisor:通知器)。

分别进入通知器的通知(advice,表示实际增强的逻辑入口)构造方法与切点(pointcut,表示哪些类或者哪些方法需要被拦截)构造方法一探究竟。

在这里插入图片描述
在这里插入图片描述
AnnotationAsyncExecutionInterceptorinvoke方法中,定义了我们的方法异步执行的逻辑:
在这里插入图片描述
上面查看了类AsyncAnnotationAdvisor中方法buildAdvice,继续进入方法buildPointcut看看:
在这里插入图片描述
这里就是把注解Async定义到了切点。

那么问题来了,Spring是在什么时候根据什么来生成了具有以上切面的代理对象?

我们再次回到类AbstractAdvisingBeanPostProcessor中,在方法postProcessAfterInitialization中有这样一部分代码:
在这里插入图片描述
这里有个重要的方法isEligible,将代码注释翻译过来:检查给定的类是否有资格向该后处理程序的通知器提供通知。
在这里插入图片描述
当重复判断的时候会直接返回,红框内的canApply会判断切面是否应该应用到当前类,其逻辑如下:
在这里插入图片描述
在这里插入图片描述
在这里会获取目标类的所有方法,并逐个匹配,如果有方法具有Async注解,则会返回true,即可以构造对应的代理对象。

因此,当我们调用相关类的某个被Async注解标注的方法时,是调用的具有切面定义的代理对象,并异步执行该方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

压缩感知的图像仿真(MATLAB源代码)

压缩感知是一种用于高效获取和表示信号的技术,它可以显著减少数据的采样和传输量,同时保持对信号的高质量恢复能力。在压缩感知中,信号被表示为其在一个稀疏基中的稀疏线性组合。通过仅使用少量的随机投影测量,就能够捕捉信号的大…

报表控件Stimulsoft 新版本2024.1中,功能区工具栏新功能

今天,我们将讨论Stimulsoft Reports、Dashboards 和 Forms 2024.1版本中的一项重要创新 - 在一行中使用功能区工具栏的能力。 Stimulsoft Ultimate (原Stimulsoft Reports.Ultimate)是用于创建报表和仪表板的通用工具集。该产品包括用于WinF…

Elasticsearch Update By Query详解

1. 使用场景 一般在以下几种情况时,我们需要重建索引: 索引的 Mappings 发生变更:字段类型更改,分词器及字典更新 索引的 Setting 发生变更:索引的主分片数发生改变 集群内,集群间需要做数据迁移 Elastiic…

【移动安全】MobSF联动安卓模拟器配置动态分析教程

原文链接 MobSF联动安卓模拟器配置动态分析教程 实现方式 Windows开启安卓模拟器并进行相关配置作为调试客户端,Linux使用docker开启MobSF作为服务端。 好处:干净,部署简单,不用安装乱七八糟的环境,防止破坏其他应…

STM32F10X(Cortex-M3)系统定时器寄存器笔记和系统定时器精准延时函数

Cortex-M3系统定时器寄存器笔记和系统定时器精准延时函数 简介系统定时器寄存器STK_CTRLSTK_LOADSTK_VALSTK_CALIB STM32F10X(Cortex-M3)精准延时函数 简介 在STM32F10X(Cortex-M3)除了通用定时器和看门狗定时器外,还有一个系统定时器(SysTick) 拿STM32F103C8T6来说…

ES6 | (一)ES6 新特性(上) | 尚硅谷Web前端ES6教程

文章目录 📚ES6新特性📚let关键字📚const关键字📚变量的解构赋值📚模板字符串📚简化对象写法📚箭头函数📚函数参数默认值设定📚rest参数📚spread扩展运算符&a…

干货分享 | TSMaster 序列发送模块在汽车开发测试中的应用

众所周知,序列发送模块可以不需要脚本代码实现测试中特定控制报文序列的发送,该模块多用于循环顺序控制的测试案例中。序列发送模块的常用场景,主要是针对一些新开发的产品需要通过该模块来验证产品功能等等。本文重点和大家分享一下关于TSMa…

力扣102 二叉树的层序遍历 Java版本

文章目录 题目描述思路代码 题目描述 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3],[…

辉辉数码:目前电视盒子哪个最好?目前性能最好的电视盒子

大家好,我是辉辉,上期测评发布后我收到了很多粉丝的反馈希望我这期能分享电视盒子推荐,看看目前电视盒子哪个最好。我购入了市面上最热门的十几款电视盒子对比配置、系统后整理了五款目前性能最好的电视盒子推荐给大家。 品牌型号&#xff1…

计算机网络-局域网和城域网(二)

1.局域网互联设备: 2层网桥(生成树、源路由)、3层交换机、路由器。网桥要求3层以上协议相同,1、2层协议不同可互联。 2.生成树网桥: 又叫透明网桥,IEEE802.1d,生成树算法。基本思想是在网桥之…

Spring Security学习(六)——配置多个Provider(存在两种认证规则)

前言 《Spring Security学习(五)——账号密码的存取》一文已经能满足一般应用的情况。但实际商业应用也会存在如下的情况:用户提交的账号密码,能在本地的保存的账号密码匹配上,或者能在远端服务认证中匹配上&#xff…

提示找不到msvcr110.dll怎么解决?这5个方法简单有效搞定

在计算机系统运行过程中,如果发现无法找到msvcr110.dll这个特定的动态链接库文件,通常会引发一系列问题和困扰。首先,这可能导致某些应用程序无法正常启动或运行,因为msvcr110.dll是许多基于Microsoft Visual C编译的应用程序所必…

如何使用Docker本地部署Jupyter+Notebook容器并结合内网穿透实现远程访问

文章目录 1. 选择与拉取镜像2. 创建容器3. 访问Jupyter工作台4. 远程访问Jupyter工作台4.1 内网穿透工具安装4.2 创建远程连接公网地址4.3 使用固定二级子域名地址远程访问 本文主要介绍如何在Ubuntu系统中使用Docker本地部署Jupyter Notebook,并结合cpolar内网穿透…

新版Java面试专题视频教程——多线程篇①

新版Java面试专题视频教程——多线程篇① Java多线程相关面试题 0. 问题汇总0.1 线程的基础知识0.2 线程中并发安全 1.线程的基础知识1.1 线程和进程的区别?1.2 并行和并发有什么区别?1.3 创建线程的四种方式1.4 runnabl…

ES6 | (二)ES6 新特性(下) | 尚硅谷Web前端ES6教程

文章目录 📚迭代器🐇定义🐇工作原理🐇自定义遍历数据 📚生成器函数🐇声明和调用🐇生成器函数的参数传递🐇生成器函数案例 📚Promise📚Set🐇Set的定…

fastApi笔记05-路径参数和数值校验

使用Path可以对路径参数声明与Query相同类型的校验和元数据 from typing import Annotatedfrom fastapi import FastAPI, Path, Queryapp FastAPI()app.get("/items/{item_id}") async def read_items(item_id: Annotated[int, Path(title"The ID of the item …

微服务篇之限流

一、为什么要限流 1. 并发的确大(突发流量)。 2. 防止用户恶意刷接口。 二、限流的实现方式 1. Tomcat限流 可以设置最大连接数,但是每一个微服务都有一个tomcat,实现起来非常麻烦。 2. Nginx限流 (1)控…

假如C++进入Linux内核,那么需要做哪些改造?

假如C进入Linux内核,那么需要做哪些改造? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家&#xf…

ChatGPT安卓版正式发布,附安装包,但有款手机无法使用

ChatGPT安卓版如约而至,OpenAI正式宣布该应用已在谷歌应用商店上架,用户可以免费下载,对话不限次数。 但是安卓版ChatGPT目前仅在美国、印度、孟加拉国和巴西提供下载,下周将会推广至更多国家。 网页端下载链接: http…

五、矩阵的运算

1、矩阵的加减: 前提:两个矩阵必须是同形矩阵。 矩阵加减具有交换律,矩阵矩阵相乘没有交换律。 计算结果:元素级运算。 2、矩阵的数乘: 计算结果:元素级运算。这里要区别与行列式的数乘。 3、矩阵与向量的乘法: 前提:矩阵的列数等于向量的行数。 计算方式:左列…