人人都能看懂的Spring源码解析,spring的事件监听机制
- 原理解析
- 事件监听机制
- ApplicationEventPublisher、ApplicationEventMulticaster、ApplicationEvent、ApplicationListener
- AbstractApplicationContext发布的事件类型
- 代码走读
- 总结
往期文章:
- 人人都能看懂的Spring底层原理,看完绝对不会懵逼
- 简单易懂的Spring扩展点详细解析,看不懂你来打我
- 人人都能看懂的Spring源码解析,配置解析与BeanDefinition加载注册
- 简单易懂又非常牛逼的Spring源码解析,ConfigurationClassPostProcessor的具体逻辑
- 简单易懂值得收藏的Spring源码解析,依赖注入和bean的初始化
- 人人都能看懂的Spring源码解析,Spring如何解决循环依赖
- 人人都能看懂的Spring源码解析,Spring如何处理AOP
- 人人都能看懂的Spring源码解析,Spring声明式事务是如何实现的
- 人人都能看懂的Spring源码解析,Spring声明式事务关于传播特性、事务挂起与恢复的处理
原理解析
事件监听机制
事件监听机制是观察者模式的一种实现方式,观察者模式里面一般有事件发布器、事件、事件监听器三个组件。事件监听器往事件发布器里面注册,事件发布器保存注册进来的事件监听器,一旦发生状态的变化,事件发布器向保存的事件监听器发布事件,通知事件监听器处理。
ApplicationEventPublisher、ApplicationEventMulticaster、ApplicationEvent、ApplicationListener
Spring中的ApplicationEventPublisher、ApplicationEvent、ApplicationListener,分别对应事件监听机制中的事件发布器、事件、事件监听器。而ApplicationEventMulticaster是事件广播器,被ApplicationEventPublisher持有,用于广播发布的事件给各个ApplicationListener。
ApplicationEventPublisher接口有一个抽象方法 void publishEvent(Object event) ,用于发布事件。
ApplicationEventMulticaster接口的抽象方法 void multicastEvent(ApplicationEvent event),用于广播事件。
ApplicationListener接口有一个抽象方法 void onApplicationEvent(E event) ,用于接收事件通知。
AbstractApplicationContext实现了ApplicationEventPublisher接口,用一个 Set<ApplicationListener<?>> 类型的变量 applicationListeners 保存注册进来的ApplicationListener。
AbstractApplicationContext有一个 void addApplicationListener(ApplicationListener<?> listener) 方法接收注册进来的ApplicationListener,然后保存到applicationListeners中。然后会调用ApplicationEventMulticaster的addApplicationListener方法,把注册进来的ApplicationListener也保存到ApplicationEventMulticaster中。
ApplicationEvent继承了EventObject,EventObject创建时需要接收一个事件源source。事件源就是触发该事件的源头。
AbstractApplicationContext发布的事件类型
AbstractApplicationContext发布的事件类型一共四种:
- ContextClosedEvent 上下文关闭事件
- ContextRefreshedEvent 上下文刷新完成事件
- ContextStartedEvent 上下文启动事件
- ContextStoppedEvent 上下文停止事件
它们都继承 ApplicationContextEvent ,而ApplicationContextEvent又继承了ApplicationEvent。与Spring上下文状态变化相关的事件都继承ApplicationContextEvent,而ApplicationEvent类型的事件则范围更广。
其中 ContextRefreshedEvent 是我们最熟悉的事件类型,会在AbstractApplicationContext的 finishRefresh() 方法中发布,而finishRefresh()又会在 refresh() 方法调用完 finishBeanFactoryInitialization(beanFactory) 方法之后被调用,也就是说Spring会在初始化完所有非懒加载单例bean之后,会发布一个上线文刷新完成事件。
代码走读
我们启动Spring应用,AbstractApplicationContext的refresh() 方法就会被调用,refresh()方法用于刷新Spring应用上下文,创建并初始化Spring容器,refresh()方法会调用finishBeanFactoryInitialization(beanFactory)进行非懒加载单例bean的初始化,调用完 finishBeanFactoryInitialization(beanFactory) 方法之后,会调用finishRefresh()方法,Spring会在这个方法里面触发上下文刷新完成事件的发布。
finishRefresh()方法会以AbstractApplicationContext作为事件源创建一个ContextRefreshedEvent事件,并调用publishEvent方法发布该事件。
publishEvent方法里面会调用getApplicationEventMulticaster()方法获取到ApplicationEventMulticaster事件广播器,然后调用ApplicationEventMulticaster的multicastEvent方法广播ContextRefreshedEvent事件给所有注册进来的ApplicationListener。
进入到SimpleApplicationEventMulticaster的multicastEvent方法,里面会调用getApplicationListeners方法获取所有的ApplicationListener,遍历每一个ApplicationListener,调用invokeListener(listener, event)方法,listener就是当前遍历到的ApplicationListener,event就是ContextRefreshedEvent事件。
invokeListener方法调用doInvokeListener方法。
doInvokeListener方法就会调用ApplicationListener的onApplicationEvent方法,通知该ApplicationListener。
总结
以上就是对于spring的事件监听机制的讲解的全部内容。spring的事件监听机制算是Spring源码里面相对简单的一块,所以本篇文章的内容也不算多。下面就对spring的事件监听机制的讲解做一个总结。
- Spring事件监听机制中最重要的四个组件分表是ApplicationEventPublisher、ApplicationEventMulticaster、ApplicationEvent、ApplicationListener。
- ApplicationEventPublisher会持有ApplicationEventMulticaster。注册到ApplicationEventPublisher的ApplicationListener也会保存一份到ApplicationEventMulticaster;ApplicationEventPublisher发布的ApplicationEvent会被ApplicationEventMulticaster广播给注册进来的所有ApplicationListener。
- ContextRefreshedEvent事件是我们最熟悉的事件类型,会在AbstractApplicationContext的finishRefresh方法中发布,而finishRefresh方法又会在AbstractApplicationContext的refresh方法中完成所有非懒加载单例bean的初始化后被调用。