【从零构建Spring|第十一节】 观察者模式实现容器事件及监听器

【从零构建Spring|第十一节】 观察者模式实现容器事件及监听器
Shio【从零构建Spring|第十一节】 观察者模式实现容器事件及监听器
Spring 为什么需要事件,可以用来干什么?
用来解耦代码。高内聚,低耦合的设计思想
可以用于处理日志监控和各种事件发布订阅的客制化定义
观察者模式
在开发中,有很多利用到解耦的场景,例如在注册事件完成后异步发送事件推送消息,用户下单后异步发送MQ消息给与用户后续业务的跟进情况,用户付完款后就可以发送货物派送进度,都是依靠事件订阅和发布以及MQ消息这样的组件,来处理系统之间的调用解耦,最终也通过解耦的方式来提升整体系统架构的稳定性和负载能力
其实解耦思想就是观察者模式的一种体现。当对象间存在一对多关系时,则适合使用观察者模式,它定义了对象之间的一种一对多依赖关系。当一个对象的状态改变时,所有依赖他,与他有关的对象都会得到通知并且自动更新。
观察者模式角色
Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。
这一节中和前几节结合起来,才更能明白 Spring 框架,在 Spring 框架中,我感觉是万物即 Bean 对象
就像本节的事件监听器,就是通过 xml 文件配置,被 ClassPathXmlApplicationContext 面向用户的应用上下文读取出来并通过 bean 对象加载。在上一节中 FactoryBean 实际上也是通过 xml 配置,读取出来实例化成 bean。只不过这个 bean 我们创建的更加简单,不需要配置引用类型。
设计
事件
在观察者模式中,我们提到一个事件想要运作,需要 事件、事件广播器(事件监听器)、事件发布器 三大部分,事件广播器实际上是一个管理 事件监听器的容器,负责处理其添加、触发。在 AbstractApplicationContext 中,initApplicationEventMulticaster和registerListeners去实现事件监听器的注册添加,因为 Spring IoC 容器中万物皆 Bean,因此监听器是由单例模式注册的,之后将所有的监听器都交由广播器来统一管理。
private void initApplicationEventMulticaster() { |
事件机制的行为如下:
同时还有专门处理容器关闭和容器刷新的监听器 ContextCloseEventListener、ContextRefreshEventListener
并且由于是事件机制,它也是异步的,当等到一个事件的发布,事件监听器才会被触发去执行相应逻辑,即调用onApplicationEvent方法完成相关逻辑
具体情况如图,事件广播器接受到事件发布之后,调用内部广播方法,遍历通知所有被管理的监听器,监听器调用各自的执行方法。完成事件订阅与接收逻辑
工程
约定接口(整个事件机制的基石)
监听器接口
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { |
发布器接口
public interface ApplicationEventPublisher { |
- 只处理发布事件的逻辑
事件广播器
/** |
自定义事件的实现
事件监听器(刷新容器、关闭容器、自定义事件监听)的实现逻辑
AbstractApplicationContext 中集成了发布事件以及添加事件监听器的逻辑,并且提供了接口,这就是我们事件的入口
如何获取这个入口
- 像测试用例一样,直接用xml去获取ClassPathXmlApplicationContext
- 通过ApplicationContextAware
ApplicationContextAware
在 AbstractApplicationContext#refresh,会为实现了 ApplicationContextAware 的类设置好对应的 ApplicationContext,那就可以通过这样获取到入口。
而这个操作的实现,是注入了一个实现了BeanPostProcessor的专门用于添加ApplicationContext的实例ApplicationContextAwareProcessor
那么由此又可以引申出,对象创建,BeanFactoryPostProcessor,ApplicationContext,Bean的生命周期,毕竟这 些都是在Bean的生命周期里实现的。
通过这章又可以回想起Cglib方式创建的对象,那是源于当时最初没有对有参构造进行特殊设置,从而有cglib和普通的反射方法创建的不同策略。
spring的IOC所进行的就是对Bean进行管理,Bean就是一个个的实例化对象(Spring IoC 中万物即 Bean 对象。每个Bean从创建到销毁,中间他是有许许多多的过程,它就使用了 ApplicationContext 进而扩展,对每个环节进行控制和扩展方法。比如对象创建前后的操作,对象感知容器,复杂对象的创建可以用另一种 FactoryBean 的方法,对事件的控制等等
参考:




















