监听器
- ApplicationListener用法
-
- 写一个监听器
- 发布事件
- ApplicationListener原理
-
- 多播器
- 注册监听器
- 发布事件 监听器方法回调
-
- 发布事件的流程
- @EventListener用法
- @EventListener原理
监听器的实现有两种方式:
- 实现ApplicationListener接口
- 加@EventListener
ApplicationListener用法
ApplicationListener通过监听容器中发布的一些事件,事件发生就会触发监听器的回调,就完成了事件驱动开发
写一个监听器
- 写一个监听器监听某个事件
- 实现ApplicationListener
- 把监听器加入到容器中
只要容器中有相关事件发布,我们就能监听到这个事件
测试结果:
监听到的两个事件
发布事件
我们也可以自己发布事件
// 发布事件
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的事件")) {
});
ApplicationListener原理
创建ioc容器,调用refresh()方法
- 第一步:多播器/派发器
this.initApplicationEventMulticaster();
- 第二步:注册监听器
this.registerListeners();
- 第三步:发布事件 监听器方法回调
不管是什么事件, 都是通过publishEvent()发布事件的流程是一样的,只是创建事件的位置不一样- ContextRefreshedEvent 事件
this.finishRefresh(); //ContextRefreshedEvent 事件在这里
- 自己发布事件(不是在refresh())
- 容器关闭事件(不是在refresh())
- ContextRefreshedEvent 事件
多播器
容器创建对象refresh() 中调用initApplicationEventMulticaster就是初始化EventMulticaster的
initApplicationEventMulticaster() 方法:
* 先去容器中找id=“applicationEventMulticaster”的
* 容器中没有就创建SimpleApplicationEventMulticaster
* 将创建好的加入到beanFactory
注册监听器
容器创建对象refresh() 中调用ApplicationListener()就是注册监听器的
ApplicationListener()方法:
就是从容器中拿到所有的监听器,把他们注册到ApplicationEventMulticaster中
发布事件 监听器方法回调
-
ContextRefreshedEvent
默认的事件:ContextRefreshedEvent,容器刷新完成事件
所以在refresh() 的finishRefresh()方法中 会发布ContextRefreshedEvent事件,然后触发监听器。finishRefresh() 如下
finishRefresh() 调用的publishEvent() 方法如下: -
我们自己写的发布事件
也是会调用发布事件的流程的publishEvent()
-
容器关闭发布事件 ContextClosedEvent
doClose()方法也会调用publishEvent() 方法
发布事件的流程
publishEvent():
-
获取事件的派发器/多播器getApplicationEventMulticaster()
-
派发事件 multicastEvent
获取到所有的ApplicationListeners,依次遍历
@EventListener用法
在想监听事件的方法上加上@EventListener注解,注解中指定要监听哪种类型的事件
然后在方法上写上参数,获得监听到的事件
看结果和实现ApplicationListener接口的结果是一样的
@EventListener原理
原理是:用EventListenerMethodProcessor处理器来解析方法上的@EventListener注解
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor
EventListenerMethodProcessor实现了SmartInitializingSingleton接口,这个接口如下:
有一个afterSingletonsInstantiated方法:
这个方法在所有单实例bean全部创建完成后 执行
在EventListenerMethodProcessor的afterSingletonsInstantiated方法处打一个断点,看运行流程如下:
-
创建ioc容器,refresh() 方法刷新容器
-
执行refresh() 中的finishBeanFactoryInitialization(beanFactory)
初始化剩下的单实例bean
-
调用preInstantiateSingletons()方法
在finishBeanFactoryInitialization中调用beanFactory.preInstantiateSingletons();
-
preInstantiateSingletons()
得到所有的beanDefinitionNames,依次遍历,是SmartInitializingSingleton类型的就调用其afterSingletonsInstantiated方法
然后就把这个标 了@EventListener注解的方法弄成listener,之后发布事件的时候 就会回调这个方法
问题是什么时候弄成listener的????
{{m.name}}