• Spring注解驱动之@EventListener注解使用


    概述

    之前我们说过可以通过实现ApplicationListener接口来监听处理事件。
    其实还有一种注解方式来监听处理事件。即使用@EventListener注解,通过该注解就可以在方法上监听事件了。这样普通的业务逻辑组件中就可以直接使用这个注解来监听事件了,无需实现ApplicationListener接口了,确实比较方便,但是其原理是和ApplicationListener接口一样的,也可以自定义一个多波器实现异步监听事件,定义方法与之前一致。Spring注解驱动之ApplicationListener异步处理事件详解

    @EventListener注解的用法

    首先,编写一个普通的业务逻辑组件,例如UserService,并在该组件上标注一个@Service注解。
    我们只需要简单的在该方法上标注一个@EventListener注解,就可以让方法来监听事件了。可以通过注解的classes属性来指定需要监听的事件。例如,我们可以让listen方法监听ApplicationEvent及其子事件。
    最后我们在参数的位置上写一个ApplicationEvent参数来接收事件,参数值是在Spring框架调用的时候自动赋值的。

    package com.meimeixia.ext;
    
    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.event.EventListener;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
    	
    	// 一些其他的方法...
    
    	@EventListener(classes=ApplicationEvent.class)
    	public void listen(ApplicationEvent event) {
    		System.out.println("UserService...监听到的事件:" + event);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    写个测试用例。

    package com.meimeixia.test;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationEvent;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.meimeixia.ext.ExtConfig;
    
    public class IOCTest_Ext {
    	
    	@Test
    	public void test01() {
    		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
    		
    		// 发布一个事件
    		applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
    		});
    		
    		// 关闭容器
    		applicationContext.close();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    你会发现Eclipse控制台打印出了如下内容,可以清晰地看到,不仅我们之前编写的监听器(例如MyApplicationListener)收到了事件,而且UserService组件也收到了事件。也就是说,每一个都能正确地收到事件。
    在这里插入图片描述

    @EventListener注解的原理

    我们可以点进去@EventListener这个注解里面去看一看,如下图所示,可以看到这个注解上面有一大堆的描述,从描述中我们可以猜到这个注解的内部工作原理。
    在这里插入图片描述
    描述中有一个醒目的字眼,即参考EventListenerMethodProcessor。意思可能是说,如果你想搞清楚@EventListener注解的内部工作原理,那么可以参考EventListenerMethodProcessor这个类。
    EventListenerMethodProcessor是一个处理器,其作用是来解析方法上的@EventListener注解的。这也就是说,Spring会使用EventListenerMethodProcessor来解析方法上的@EventListener注解。因此,搞清楚这个处理器是怎样工作的,就搞清楚了@EventListener注解的内部工作原理。
    在这里插入图片描述
    在这里插入图片描述
    仔细看一下SmartInitializingSingleton接口中afterSingletonsInstantiated方法上面的描述信息,不难看出该方法是在所有的单实例bean已经全部被创建完了以后才会被执行。
    在介绍SmartInitializingSingleton接口的时候,我们也能从描述信息中知道,在所有的单实例bean已经全部被创建完成以后才会触发该接口。紧接着下面一段的描述还说了,该接口的调用时机有点类似于ContextRefreshedEvent事件,即在容器刷新完成以后,便会回调该接口。也就是说,这个时候容器已经创建完了。
    如果所有的单实例bean都已经创建完了,也就是说下面这一步都执行完了,那么说明IOC容器已经创建完成了。
    在这里插入图片描述
    紧接着便会来调用finishRefresh方法,容器已经创建完了,此时就会来发布容器已经刷新完成的事件。这就呼应了开头的那句话,即SmartInitializingSingleton接口的调用时机有点类似于ContextRefreshedEvent事件,即在容器刷新完成以后,便会回调该接口。

    参考

    Spring注解驱动开发第40讲——你晓得@EventListener这个注解的原理吗?

  • 相关阅读:
    Linux高可用(HA)集群keepalived基础概念
    MySQL之MHA
    Win10 update version 22H2
    如何缓解失业无收入焦虑状态?
    Vue脚手架
    ThreadLocal是什么?
    Sentinel 源码学习
    rails常用小技巧合集(一)
    零基础最简单方式学习Linux?
    笔记:Android 应用启动流程
  • 原文地址:https://blog.csdn.net/tianzhonghaoqing/article/details/126921979