当前位置:首页 > 科技  > 软件

Spring事件如何异步执行?

来源: 责编: 时间:2024-03-18 09:42:49 121观看
导读环境:SpringBoot2.7.161. 简介ApplicationContext 中的事件处理是通过 ApplicationEvent 类和 ApplicationListener 接口提供的。如果在上下文中部署了实现 ApplicationListener 接口的 Bean,那么每次 ApplicationEvent

环境:SpringBoot2.7.167fs28资讯网——每日最新资讯28at.com

1. 简介

ApplicationContext 中的事件处理是通过 ApplicationEvent 类和 ApplicationListener 接口提供的。如果在上下文中部署了实现 ApplicationListener 接口的 Bean,那么每次 ApplicationEvent 发布到 ApplicationContext 时,都会通知该 Bean。从本质上讲,这就是标准的观察者设计模式。7fs28资讯网——每日最新资讯28at.com

7fs28资讯网——每日最新资讯28at.com

从Spring 4.2开始,事件基础设施得到了显著改进,并提供了基于注释的模型以及发布任意事件的能力(也就是说,不一定是从ApplicationEvent扩展的对象)。当这样的对象被发布时,我们将它包装在一个事件中。7fs28资讯网——每日最新资讯28at.com

7fs28资讯网——每日最新资讯28at.com

以下是一个简单的事件应用7fs28资讯网——每日最新资讯28at.com

1.1 定义事件对象

public class PackEvent extends ApplicationEvent {  private static final long serialVersionUID = 1L;  public PackEvent(Object source) {    super(source);  }}

1.2 定义事件监听

@Componentpublic class PackEventListener implements ApplicationListener<PackEvent> {  @Override  public void onApplicationEvent(PackEvent event) {    System.out.println("触发事件...") ;  }}

1.3 发布事件

@Resourceprivate ApplicationEventMulticaster eventMulticaster ;public void run(ApplicationArguments args) throws Exception {  eventMulticaster.multicastEvent(new PackEvent("自定义Pack")) ;}

以上Spring事件系统的完整应用实例。在默认情况下该种事件处理方式是同步的,也就是事件的发布者与事件的处理都是同一个线程中,那这就要求我们的事件处理程序不应该处理复杂耗时的任务,否则会影响我们的主业务系统。那如何异步处理事件呢?7fs28资讯网——每日最新资讯28at.com

2. 事件异步处理

2.1 通过@Async注解

该种方式是最简单的方式了,开启异步功能,在基于注解的事件监听方法上使用@Async注解。7fs28资讯网——每日最新资讯28at.com

开启异步任务功能更7fs28资讯网——每日最新资讯28at.com

@EnableAsyncpublic class AppApplication {}

基于注解事件监听7fs28资讯网——每日最新资讯28at.com

@Async@EventListener({PackEvent.class})public void packEventListener(PackEvent event) {  System.out.printf("%s - 事件发生了...%s%n", Thread.currentThread().getName(), event.getSource()) ;}

执行结果7fs28资讯网——每日最新资讯28at.com

task-1 - 事件发生了...自定义Pack

线程名已经变为了task-1。task-前缀是异步线程的默认名。关于异步任务执行应用的线程池配置,查看下面这篇文章。7fs28资讯网——每日最新资讯28at.com

Spring任务调度&异步任务&Web异步请求三者如何配置线程池?7fs28资讯网——每日最新资讯28at.com

上面是基于注解的方式应用异步执行事件处理。对于在简介中通过实现ApplicationListener接口的方式又该如何处理呢?7fs28资讯网——每日最新资讯28at.com

对于这种方式,我们可以通过两种方式进行处理:7fs28资讯网——每日最新资讯28at.com

2.2 自定义线程池

  • 在事件监听处理程序中开启异步线程
@Componentpublic class PackEventListener implements ApplicationListener<PackEvent> {  @Override  public void onApplicationEvent(PackEvent event) {    new Thread(() -> {      System.out.printf("%s触发事件...%n", Thread.currentThread().getName()) ;    }).start() ;  }}
  • 自定义事件广播器
@BeanTaskExecutor taskExecutor() {  ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor() ;  taskExecutor.setThreadNamePrefix("pack-event-") ;  taskExecutor.setCorePoolSize(5) ;  taskExecutor.setQueueCapacity(100) ;  taskExecutor.setMaxPoolSize(5) ;  taskExecutor.initialize() ;  return taskExecutor ;}// 注意beanName必须为applicationEventMulticaster;下面的源码中你将看到@Bean(name  = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME)SimpleApplicationEventMulticaster eventMulticaster(BeanFactory beanFactory) {  SimpleApplicationEventMulticaster eventMulticaster = new SimpleApplicationEventMulticaster(beanFactory) ;  eventMulticaster.setTaskExecutor(taskExecutor()) ;  return eventMulticaster ;}

通过这种方式也可以实现事件处理程序异步执行。而这种方式的实现原理如下:7fs28资讯网——每日最新资讯28at.com

容器启动中的核心方法refresh中7fs28资讯网——每日最新资讯28at.com

public abstract class AbstractApplicationContext {  public void refresh() {    // 初始化事件广播器    initApplicationEventMulticaster();  }  protected void initApplicationEventMulticaster() {    ConfigurableListableBeanFactory beanFactory = getBeanFactory();    // 判断容器中是否存在beanName=applicationEventMulticaster    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {      this.applicationEventMulticaster =          beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);    } else {      // 如果不存在则创建一个同步的执行器。      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);    }  }}

以上是本篇文章的全部内容,希望对你有帮助。7fs28资讯网——每日最新资讯28at.com

完毕!!!7fs28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-76561-0.htmlSpring事件如何异步执行?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Spring中Cron表达式的优雅实现方案

下一篇: OpenFeign夺命连环九问

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 红魔电竞平板评测:大屏幕硬实力

    红魔电竞平板评测:大屏幕硬实力

    前言:三年的疫情因为要上网课的原因激活了平板市场,如今网课的时代已经过去,大家的生活都恢复到了正轨,这也就意味着,真正考验平板电脑生存的环境来了。也就是面对着这种残酷的
  • 7月安卓手机好评榜:三星S23Ultra好评率第一

    7月安卓手机好评榜:三星S23Ultra好评率第一

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年7月1日至7月31日,仅限国内市场。第一名:三星Galaxy S23 Ultra好评率:95.71%在即将迎来新
  • 0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    旭日森林无糖仙草乌龙茶510ml*15瓶平时要卖为79.9元,今日下单领取50元优惠券,到手价为29.9元。产品规格:0糖0卡0脂,添加草本仙草汁,清凉爽口,富含茶多酚,保留
  • SpringBoot中使用Cache提升接口性能详解

    SpringBoot中使用Cache提升接口性能详解

    环境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPASpring 框架从 3.1 开始,对 Spring 应用程序提供了透明式添加缓存的支持。和事务支持一样,抽象缓存允许一致地使用各
  • 三分钟白话RocketMQ系列—— 如何发送消息

    三分钟白话RocketMQ系列—— 如何发送消息

    我们知道RocketMQ主要分为消息 生产、存储(消息堆积)、消费 三大块领域。那接下来,我们白话一下,RocketMQ是如何发送消息的,揭秘消息生产全过程。注意,如果白话中不小心提到相关代
  • 回归OPPO两年,一加赢了销量,输了品牌

    回归OPPO两年,一加赢了销量,输了品牌

    成为OPPO旗下主打性能的先锋品牌后,一加屡创佳绩。今年618期间,一加手机全渠道销量同比增长362%,凭借一加 11、一加 Ace 2、一加 Ace 2V三款爆品,一加
  • 电博会与软博会实现

    电博会与软博会实现"线下+云端"的双线融合

    在本次“电博会”与“软博会”双展会利好条件的加持下,既可以发挥展会拉动人流、信息流、资金流实现快速交互流动的作用,继而推动区域经济良性发展;又可以聚
  • “买真退假” 这种“羊毛”不能薅

    “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
Top