​@Async​

news2024/12/22 13:41:51

Spring框架中的 ​@Async​注解是为了支持异步方法调用而设计的。

异步方法调用是指调用方在发起方法调用后,不需要等待被调用方法的结果返回,而是可以立即继续执行其他任务。这种方式能够提高系统的并发性和响应性,特别适用于一些耗时较长、不需要立即获取结果的操作。

Spring引入了 ​@Async​注解来实现异步方法调用。使用 ​@Async​注解修饰的方法会在执行时自动开启一个新的线程,使得方法可以异步执行。同时,Spring还提供了与 ​@Async​注解配套使用的任务执行器(TaskExecutor)来管理线程池,以便更好地控制异步任务的并发度和资源消耗。

@Async​注解的原理如下:

  1. Spring使用AOP(面向切面编程)技术对被 ​@Async​注解修饰的方法进行代理。
  2. 在运行时,当调用带有 ​@Async​注解的方法时,实际上是调用了代理对象的方法。
  3. 代理对象会将目标方法的调用包装在一个 ​Future​对象中,并立即返回给调用方,不阻塞主线程。
  4. 代理对象使用设定的任务执行器(TaskExecutor)来执行异步任务,将实际的方法调用放在一个新的线程中进行。
  5. 当异步任务执行完毕后,会将结果封装在 ​Future​对象中,并提供给调用方获取。

在Spring源码中,​@Async​注解的实现主要依赖于两个核心组件:​AsyncAnnotationBeanPostProcessor​和 ​TaskExecutor​。

  1. ​AsyncAnnotationBeanPostProcessor​:它是一个Bean后置处理器,负责解析并处理带有 ​@Async​注解的方法。在Spring容器初始化时,它会扫描所有的Bean定义,找到所有具有 ​@Async​注解的方法,并对其进行代理。它使用了Spring的AOP功能,通过创建代理对象来拦截异步方法的调用。

  2. ​TaskExecutor​:它是任务执行器,用于管理执行异步任务的线程池。Spring提供了多种内置的任务执行器实现,如 ​SimpleAsyncTaskExecutor​、​ThreadPoolTaskExecutor​等。开发人员可以根据需要选择适合自己应用场景的任务执行器。

下面以一个简单的例子来说明 ​@Async​注解的使用和原理:

@Service
public class MyService {
    
    @Async
    public void performAsyncTask() {
        // 异步执行的任务代码
    }
}

 在上述示例中,​MyService​类中的 ​performAsyncTask​方法被 ​@Async​注解修饰,表示该方法将以异步方式执行。

当应用程序启动时,​AsyncAnnotationBeanPostProcessor​会被Spring容器识别为一个Bean后置处理器,并被自动应用于所有的Bean。

当调用 ​MyService​的 ​performAsyncTask​方法时,实际上是通过代理对象进行调用。代理对象会将方法包装在一个 ​Future​对象中,并立即返回给调用方。同时,代理对象会将实际的方法调用提交给配置好的任务执行器。

任务执行器根据配置的线程池策略,从线程池中获取一个空闲的线程来执行异步任务。异步任务执行完毕后,将结果封装在 ​Future​对象中,以供调用方获取。

​@Async​注解的原理和执行流程:

  1. 在应用程序启动时,Spring容器会扫描所有的Bean定义,包括带有 ​@Async​注解的方法。

  2. 当包含 ​@Async​注解的方法被调用时,实际上是通过动态代理机制来进行方法的拦截和处理。

  3. 在调用带有 ​@Async​注解的方法时,代理对象会将方法的实现包装在一个 ​AsyncExecutionInterceptor​对象中,并立即返回给调用方,不阻塞主线程。

  4. ​AsyncExecutionInterceptor​是 ​AsyncAnnotationAdvisor​的内部类,在方法调用前后进行拦截并执行特定的逻辑。

  5. 当被拦截的方法需要执行时,代理对象将其提交给配置好的 ​TaskExecutor​来执行异步任务。​TaskExecutor​负责创建新线程或从线程池中获取空闲的线程来执行方法。

  6. 异步任务完成后,会将结果封装在一个 ​Future​对象中,并通过回调机制通知调用方。

通过动态代理技术,​@Async​注解使得异步方法的调用变得非常简单。当使用 ​@Async​注解标记的方法被调用时,实际上是通过代理对象来执行。代理对象会将异步任务提交给配置好的 ​TaskExecutor​来执行,不阻塞主线程。一旦异步任务完成,将结果封装在 ​Future​对象中,以供调用方获取。整个过程中,Spring利用了AOP和动态代理的机制,使得异步方法的实现变得更加灵活和高效。 

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

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

相关文章

算法练习- 其他算法练习5

文章目录 宜居星球改造计划 宜居星球改造计划 yes no na 每个值为一个格子;每天yes的值可以向上下左右扩展一个格子,将no改为yes;矩形区域no是否可以全部转为yes,可以的话需要几天?不可以的话输出-1输入: …

高性能服务器Nodejs业务实战

目录 1 项目初始化1.1 创建项目1.2 配置 cors 跨域1.3 配置解析表单数据的中间件1.4 初始化路由相关的文件夹1.5 初始化用户路由模块1.6 抽离用户路由模块中的处理函数 2 登录注册2.1 新建 ev_users 表2.2 安装并配置 mysql 模块2.3 注册2.4 优化 res.send() 代码2.5 优化表单数…

cuml机器学习GPU库 sklearn升级版AutoDL使用

CUML库 最近在做机器学习任务的时候发现我自己的数据集太大,直接用sklearn 跑起来时间很长,然后问GPT得知了有CUML库,后来去研究了一下,发现这个库只支持linux系统,从官网直接获取下载命令基本上也实现不了最后&#…

自学设计模式(类图、设计原则、单例模式 - 饿汉/懒汉)

设计模式需要用到面向对象的三大特性——封装、继承、多态(同名函数具有不同的状态) UML类图 eg.—— 描述类之间的关系(设计程序之间画类图) : public; #: protected; -: private; 下划线: static 属性名:类型(默认值…

如果将PC电脑变成web服务器:利用Nignx反向代理绕过运营商对80端口封锁

如果将PC电脑变成web服务器:利用Nignx反向代理绕过运营商对80端口封锁 在上一篇文章中,我们已经实现了内网主机的多次端口映射,将内网主机的端口映射到了公网,可以通过公网访问该主机了。 因为电信的家庭宽带,默认是…

SpringBoot读取Nacos配置文件

断点到ClientWorker类的getServerConfig方法,反向Debug。

2023-8-23 Trie字符串统计

题目链接&#xff1a;Trie字符串统计 #include <iostream>using namespace std;const int N 100010;int son[N][26], cnt[N],idx;char str[N];void insert(char str[]) {int p 0;for(int i 0; str[i]; i){int u str[i] - a;if(!son[p][u]) son[p][u] idx;p son[p…

Langchain+LLM

LangChain是一个开源框架&#xff0c;允许开发人员在与人工智能&#xff08;AI&#xff09;一起工作时将大型语言模型&#xff08;如GPT4&#xff09;与外部计算和数据源相结合&#xff08;它提供了一套工具、组件和接口&#xff0c;可简化创建由LLM提供支持的应用程序&#xf…

前端进阶Html+css09----BFC模型

1.什么是BFC模型 全称是&#xff1a;Block formatting context&#xff08;块级格式化上下文&#xff09;&#xff0c;是一个独立的布局环境&#xff0c;不受外界的影响。 2.FC,BFC,IFC 元素在标准流里都属于一个FC&#xff08;Formatting Context&#xff09;。 块级元素的布…

【图像分割】理论篇(2)经典图像分割网络基于vgg16的Unet

UNet 是一种用于图像分割任务的深度学习架构&#xff0c;最早由 Olaf Ronneberger、Philipp Fischer 和 Thomas Brox 在2015年的论文 "U-Net: Convolutional Networks for Biomedical Image Segmentation" 中提出。UNet 在医学图像分割等领域取得了显著的成功&#x…

Anaconda安装教程以及深度学习环境搭建

目录 前言 下载Anaconda 虚拟环境的搭建 在pycharm中配置现有的conda环境 CUDA简介 下载安装pytorch包 前言 最近换新笔记本了&#xff0c;要重新安装软件&#xff0c;以前本来是想要写这个教程的&#xff0c;但当时由于截图不全还要懒得再下载重装&#xff0c;就放弃了&…

JavaSE【继承和多态】(1)(重点:初始化、pretected封装、组合)

一、继承 继承 (inheritance) 机制 &#xff1a;是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特 性 的基础上进行扩展&#xff0c;增加新功能 &#xff0c;这样产生新的类&#xff0c;称 派生类 。 继承呈现了面向对象程序设计的层次结…

TRON归集回调

简介 设计一个通过调用api创建对应的tron地址&#xff0c;当地址收到token的时候&#xff0c;进行归集&回调通知的。包括的功能有: 根据UID创建地址归集&#xff08;TRX归集 TRC10归集 TRC20归集)回调通知&#xff08;转出回调通知&接收回调通知&#xff09;发起转出…

什么是JVM ?

一、JVM 简介 JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java 虚拟机。 虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。 常见的虚拟机&#xff1a; JVM 、 VMwave 、 Virtual Box 。 JVM 和其他两个虚拟机的区别…

《JVM修仙之路》初入JVM世界

《JVM修仙之路》初入JVM世界 博主目前正在学习JVM的相关知识&#xff0c;想以一种不同的方式记录下&#xff0c;娱乐一下 清晨&#xff0c;你睁开双眼&#xff0c;看到刺眼的阳光&#xff0c;你第一反应就是完了完了&#xff0c;又要迟到了。刚准备起床穿衣的你突然意识到不对&…

Netty核心源码解析(三)--NioEventLoop

NioEventLoop介绍 NioEventLoop继承SingleThreadEventLoop,核心是一个单例线程池,可以理解为单线程,这也是Netty解决线程并发问题的最根本思路--同一个channel连接上的IO事件只由一个线程来处理,NioEventLoop中的单例线程池轮询事件队列,有新的IO事件或者用户提交的task时便执…

Centos7 安装Docker 详细多图版

配置要求 Docker CE&#xff08;社区免费版&#xff09; 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0c; CentOS 7 满足最低内核的要求&#xff0c;所以我们在CentOS 7安装Docker。 一、Centos安装Docker 1.1 卸载&#xff08;可选&#xff0…

项目:点餐系统2

httplib的思想简单总结; 使用线程池来处理请求由用户定义处理函数&#xff0c;告诉httplib哪个请求应该使用哪个函数处理线程接收请求并解析请求后调用处理函数 一、服务器搭建 get主要是用来获取资源的&#xff0c;post主要是客户端提交数据的。 #include"httplib.h"…

小白带你学习linux的shell脚本基础(三十五)

目录 一、概述 1、脚本就是将手动一次性执行的命令进行规范且自动化 2、学习路径 2.1表达式 2.2语句 2.3函数 2.4正则表达式 2.5文件操作四剑客 二、表达式 1、shell 2、表达式 2、1 变量 2、2 运算符 2、3shell脚本编写规范 2、4shell运行规则 2、5shell脚本运…

SpringSecurity原理

最近在研究SpringSecurity&#xff0c;肝了好多天&#xff0c;算是有点收获&#xff0c;在这里分享下 SpringSecurity是什么&#xff1f; SpringSecurity是一个强大的可高度定制的认证和授权框架&#xff0c;对于Spring应用来说它是一套Web安全标准。SpringSecurity注重于为J…