博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring ApplicationListener&ApplicationEvent
阅读量:7056 次
发布时间:2019-06-28

本文共 3133 字,大约阅读时间需要 10 分钟。

本篇主要来聊一聊spring中ApplicationListener接口和ApplicationEvent类。

从命名上可以很容易的看出来一个是listener另一个是被监听的事件,但是spring是如何做到listener去监听event?同时我们该如何在日常开发过程中使用spring为我们提供的这一个监听模式?

0x01 listener和event关系

  • spring启动后会为我们创建好一个上下文,也即是我们经常听到的spring IOC的上下文ApplicationContext,可以理解ApplicationContext中是初始化了所有在.xml文件配置的bean标签的bean。

  • 我们通过在.xml文件中定义一个listener的bean,这个listener用来监听event,listener通过实现方法com.boyu.budmw.test.AppListener#onApplicationEvent来对event进行处理。

  • listener准备好了我们可以开始向ApplicationContext中发布event,当event发布后,所有在ApplicationContext中的listener都会收到对应的event。

0x02 如何使用listener和event这一特性

  1. 定义event

    首先我们要定义一个event,不然拿什么来触发?

    public class AppEvent extends ApplicationEvent {    public AppEvent(Object source) {        super(source);    }    public void sayHi(){        System.out.println("sayHi");    }}

    定义一个event非常简单,但是需要注意,这里一定要实现带有一个参数的构造函数,因为父类ApplicationEvent中没有默认的构造方法,所以子类必须重载构造函数。

  2. 定义listener

    public class AppListener implements ApplicationListener {    public void onApplicationEvent(ApplicationEvent event) {        if(!(event instanceof AppEvent)){            return ;        }        AppEvent appEvent = (AppEvent)event;        appEvent.sayHi();    }}

    上面是一个listener的实现类,listener类必须实现ApplicationListener接口,同时要实现接口中的onApplicationEvent方法,这个方法会接收到一个event,然后可以对这个event进行处理了。

    将listener类注入到spring的ApplicationContext中。<bean id="appListener" class="com.boyu.budmw.test.AppListener" />

  3. 测试listener和event

    public class ListenerTest {    public static void main (String args[]){        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/config/applicationContext.xml");        AppEvent appEvent = new AppEvent("appEvent");        applicationContext.publishEvent(appEvent);    }}

    通过org.springframework.context.ApplicationEventPublisher#publishEvent方法将event发布到spring应用上下文中,同时这个动作会触发listener收到event事件。

0x03 深入剖析发布与监听的过程

在使用org.springframework.context.ApplicationEventPublisher#publishEvent方法发布event的时候,最终会调用到spring中的org.springframework.context.event.SimpleApplicationEventMulticaster类的如下的一段代码。

当然这也是取决于你有没有对applicationEventMulticaster进行定制,如果定制了,会走到你自己定制的逻辑,下面这段是spring默认的一段逻辑。

public void multicastEvent(final ApplicationEvent event) {        for (final ApplicationListener listener : getApplicationListeners(event)) {            Executor executor = getTaskExecutor();            if (executor != null) {                executor.execute(new Runnable() {                    @SuppressWarnings("unchecked")                    public void run() {                        listener.onApplicationEvent(event);                    }                });            }            else {                listener.onApplicationEvent(event);            }        }    }
  • 这段代码一看挺简单,通过org.springframework.context.event.AbstractApplicationEventMulticaster#getApplicationListeners(org.springframework.context.ApplicationEvent)这个方法获得applicationContext中所有的listener,然后依次调用各个listener。

  • getApplicationListeners这个方法中的逻辑是从beanFactory中获取所有的ApplicationListener对象。

0x04 这个特性有什么用?

  • 当然这里也只能谈谈自己认识到的应用场景,event中可以定义一些复杂的对象或者叫服务,这样服务提供者就和服务的使用者彻底解耦了。

  • 根据自己的业务场景可以做很多事情,期待你的补充。

0x05 参考

  • 这篇我想最有参考价值的东西还是spring的源码,可以去调试相关的代码。spring有很多有价值或者说值得学习的设计思想,同样编码的规范也可以让你学到很多,多多跟着自己的思维去调试spring源码。

转载地址:http://mglol.baihongyu.com/

你可能感兴趣的文章
springMVC参数的获取区别
查看>>
win7电脑数字键盘失灵怎么办
查看>>
java及java web学习笔记
查看>>
SpringMVC+Spring+hibernate整合及分页
查看>>
OpenAI教程
查看>>
LeetCode:459. Repeated Substring Pattern
查看>>
Database Resource website
查看>>
牛客寒假6-E.海啸
查看>>
linq 读取xml
查看>>
const 总结
查看>>
@RestController注解下返回到jsp视图页面
查看>>
搜索框请输入关键字 onfocus 和 onblur
查看>>
随手记:IDAPro蛮强大
查看>>
maven的下载以及安装
查看>>
数组排序
查看>>
前端性能优化-----转发的
查看>>
CentOS 7 开放防火墙端口 命令
查看>>
深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap
查看>>
HDU 1181 变形课 【DFS】
查看>>
MySQL事务
查看>>