​@Async​

news/2024/7/1 2:58:11

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://lihuaxi.xjx100.cn/news/1475350.html

相关文章

IntelliJ IDEA maven配置,设置pom.xml的配置文件

IntelliJ IDEA项目,选择 文件 设置,弹窗 构建、执行、部署 构建工具 Maven就可以 maven配置好以后,在pom.xml的配置文件中就可以设置对应的jar包了,这样构建的时候自动需要的jar,在项目中导入即 需要的jar包设置在po…

8_分类算法-k近邻算法(KNN)

文章目录 1 KNN算法1.1 KNN算法原理1.2 KNN过程1.3 KNN三要素1.4 KNN分类预测规则1.5 KNN回归预测规则1.6 KNN算法实现方式(重点)1.7 k近邻算法优缺点 2 KD-Tree2.1 KD Tree构建方式2.2 KD Tree查找最近邻2.3 KNN参数说明 1 KNN算法 定义:如…

利用torchvision库实现目标检测与语义分割

一、介绍 利用torchvision库实现目标检测与语义分割。 二、代码 1、目标检测 from PIL import Image import matplotlib.pyplot as plt import torchvision.transforms as T import torchvision import numpy as np import cv2 import randomCOCO_INSTANCE_CATEGORY_NAMES …

视频集中存储/直播点播平台EasyDSS内核无法启动是什么原因?

视频推拉流EasyDSS视频直播点播平台,集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体,可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 有用户反馈,下载了视频直播点播平台EasyDSS最新版本&a…

STM32F103C8T6引脚图及引脚功能说明

内容部分引用STM32F103C8T6引脚图_karwen2020的博客-CSDN博客_stm32引脚图

Unity血条制作

一、使用UGUI制作血条 我一般使用image制作血条,当然,也可以使用滑动组件Slider。image的具体操作步骤如下 普通血条 1、在Hierarchy面板中,创建两个image组件,将其中一个设置为另外一个的子节点 2、在Inspector面板中&#…

【Eclipse】汉化简体中文教程(官方汉化包,IDE自带软件安装功能),图文详情

目录 0.环境 1.步骤 1)查看eclipse的版本 2)在官网找语言包,并复制链接 3)将链接复制到eclipse中 4)汉化完成 0.环境 windows11,64位; eclipse 2021-6版本 1.步骤 思路:在官网找…

数据结构 day1

1>x.mind 2>间接定义结构体数组,进行4种方式的定义和初始化 3>定义结构体存储10辆车(车的信息:品牌、单价、颜色) 1.定义函数,实现循环输入 2.定义函数,实现排序 3.定义函数,计算红色车…