返回顶部
首页 > 资讯 > 后端开发 > Python >Spring注解驱动之ApplicationListener异步处理事件说明
  • 858
分享到

Spring注解驱动之ApplicationListener异步处理事件说明

2024-04-02 19:04:59 858人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录概述示例自定义事件多波器测试用例ApplicationListener异步执行源码分析概述 之前我们讲过简单使用ApplicationListener发布事件,处理事件,但是发现

概述

之前我们讲过简单使用ApplicationListener发布事件,处理事件,但是发现是同一个线程发送事件并自己处理事件的。

下面我们就来说下如何使用自定义的线程池来异步处理接收的事件。

示例

实现一个ApplicationListener用于处理事件

package com.atguigu.ext;

import org.springframework.context.ApplicationListener;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationListener implements ApplicationListener<PayloadApplicationEvent> {

    public void onApplicationEvent(PayloadApplicationEvent applicationEvent) {
        System.out.println("exe thread start:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
        System.out.println("收到事件:" + applicationEvent);
        System.out.println(applicationEvent.getPayload());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("exe thread end:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
    }
}

自定义事件多波器

package com.atguigu.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.SimpleApplicationEventMulticaster;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
@ComponentScan("com.atguigu.ext")
public class ExtConfig {

    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster() {
        SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
        BlockingQueue<Runnable> blockingQueue = new LinkedBlockingDeque<>(1000);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 10, TimeUnit.SECONDS, blockingQueue);
        simpleApplicationEventMulticaster.setTaskExecutor(threadPoolExecutor);
        return simpleApplicationEventMulticaster;
    }
}

之前看源码可以发现,在容器创建的refresh方法中的initApplicationEventMulticaster()方法执行时,先从容器中获取name为applicationEventMulticaster的组件,如果获取不到就好创建一个默认的applicationEventMulticaster组件,该组件默认是不会设置taskExecutor任务执行器的,所以这里我们自定义一个设置了TaskExecutor的多波器,当执行initApplicationEventMulticaster方法从beanFactory中获取applicationEventMulticaster组件时,走getBean逻辑。

BeanFactory.getBean()逻辑是先从容器查看是否有该组件,如果没有获取该组件的定义,如果有定义就会创建一个组件返回并把组件保存到容器中。

测试用例

package com.atguigu;

import com.atguigu.config.ExtConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


public class AnnotationTest {
    public static void main(String[] args) {
        final AnnotationConfigApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(ExtConfig.class);
        System.out.println("main thread start:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
        applicationContext.publishEvent("发送事件");
        System.out.println("main thread end:" + Thread.currentThread().getName() + ", time:" + System.currentTimeMillis());
        applicationContext.close();
    }
}

测试结果

main thread start:main, time:1663499481185
main thread end:main, time:1663499481188
exe thread start:pool-1-thread-1, time:1663499481188
收到事件:org.springframework.context.PayloadApplicationEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@5ebec15: startup date [Sun Sep 18 19:11:20 CST 2022]; root of context hierarchy]
发送事件
九月 18, 2022 7:11:21 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5ebec15: startup date [Sun Sep 18 19:11:20 CST 2022]; root of context hierarchy
exe thread end:pool-1-thread-1, time:1663499484198

通过测试结果可以看出,main线程很快就返回了,而实际处理事件的线程是pool-1-thread-1,等待了3s多才返回。

ApplicationListener异步执行源码分析

参考:Spring注解驱动之ApplicationListener用法

与上面同步执行不同的地方就是使用了自定义的多波器里面的线程池执行了事件处理。

多波器的获取。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: Spring注解驱动之ApplicationListener异步处理事件说明

本文链接: https://lsjlt.com/news/168735.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作