Spring事件监听模型
1.案例
在开始分析前我们先来段小demo,便于后面分析。
-
环境准备
Java、Maven、Spring
-
工具
IDEA、电脑
Spring框架主要提供了ApplicationListener事件监听,只需要我们手动实现该接口就能达到监听效果。
(1)我们首先定义一个Car实体类,提供一个无参构造
public class Car {
public Car(){
System.out.println("创建实例");
}
}
(2)定义MyApplicationListener类去实现监听器ApplicationListener并将类注册到ioc容器
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent>{
//当事件到达后会触发该事件
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("收到事件===》"+event);
}
}
(3)定义配置类CarsConfig,实现对Car类的配置及包扫描
@Configuration
@ComponentScan("org.example.bean.listener")
public class CarsConfig {
@Bean
public Car car(){
return new Car();
}
}
(4)测试
public class testApp {
public static void main(String[] args) {
//创建上下文
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CarsConfig.class);
//关闭容器
context.close();
}
}
(5)控制台显示
可以看出来已经监听到容器刷新完成及容器关闭的事件,接下来我们自己来发布事件。
(6)自定义发布事件类
public class MyEvent extends ApplicationEvent {
public MyEvent(Object source) {
super(source);
}
}
(7)测试类
public class testApp {
public static void main(String[] args) {
//创建上下文
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CarsConfig.class);
//发布事件,将自己的类加入进来
context.publishEvent(new MyEvent("自定义事件"));
context.close();
}
}
(8)控制台
我们可以看到自定义发布的事件已经被监听到了,那原理是怎么呢?接下来我们将刨析底层源码实现。
2、事件监听源码分析
首先从测试类AnnotationConfigApplicationContext这个类开始跟踪,进入可以看到刷新容器refresh()方法,,继续跟进,这个方法做了容器准备、bean工厂的准备、注册后置处理器等工作,我们往下便可以看到完成刷新finishRefresh()方法,继续跟进,此时我们可以看到内部有个publishEvent发布事件的方法,其方法参数就是容器刷新完毕监听的事件。
接着继续跟进,在publishEvent方法里面进行了当前事件是否是ApplicationEvent事件的实例判断,判断了earlyApplicationEvents事件是否为空,如果为空则进入getApplicationEventMulticaster().multicastEvent这个 方法派发事件。
在这里梳理以下事件发布的流程,首先通过getApplicationEventMulticaster()获取事件的派发器(多播器)意思是即将事件发布给各自的监听器,调用方法multicastEvent派发事件,进入方法multicastEvent内部,可以看到是ApplicationEventMulticaster接口的一个抽象方法,我们找到它间接实现类SimpleApplicationEventMulticaster重写的multicastEvent这个方法,方法内部循环获取ApplicationListener事件,判断是否有Executor,有则使用Executor进行异步派发事件,没有则同步的方法执行listener方法拿到listener回调onApplicationEvent方法。
再来跟进源码到了SimpleApplicationEventMulticaster类下的invokeListener方法,使用给定的事件调用给定的侦听器,继续跟进,然后到doInvokeListener方法。
最后进入,看到了listener.onApplicationEvent方法,此方法就是我们前面自定义的监听器实现ApplicationListener类后,重写的方法onApplicationEvent,当事件到达时就会触发该方法。
本文来自博客园,作者:猿大佛,转载请注明原文链接:https://www.cnblogs.com/hushaoz/p/15484126.html