GHOST系统之家 - Windows系统光盘下载网站!
当前位置:GHOST系统之家>电脑问题 > 更上层楼,基于观察者实现,容器事件和事件监听器

更上层楼,基于观察者实现,容器事件和事件监听器

来源:Ghost系统之家浏览:时间:2022-12-31 13:16:31

本文转载自微信公众号「bugstack虫洞栈」,作者小傅哥 。转载本文请联系bugstack虫洞栈公众号。

目录

  • 一、前言
  • 二、目标
  • 三、方案
  • 四、实现
    • 1. 工程结构
    • 2. 定义和实现事件
    • 3. 事件广播器
    • 4. 事件发布者的定义和实现
  • 五、测试
    • 1. 创建一个事件和监听器
    • 2. 配置文件
    • 3. 单元测试
  • 六、总结
  • 七、系列推荐

一、前言

能解耦,是多么重要的一件事情!

摔杯为号、看我眼色行事、见南面火起,这是在嘎哈么?这其实是在通过事物传播进行解耦引线和炸弹,仅仅是这样的一个解耦,它放到了多少村夫莽汉,劫了法场,篡了兵权!

这样的解耦场景在互联网开发的设计中使用的也是非常频繁,如:这里需要一个注册完成事件推送消息、用户下单我会发送一个MQ、收到我的支付消息就可以发货了等等,都是依靠事件订阅和发布以及MQ消息这样的组件,来处理系统之间的调用解耦,最终通过解耦的方式来提升整体系统架构的负载能力。

其实解耦思路可以理解为设计模式中观察者模式的具体使用效果,在观察者模式中当对象间存在一对多关系时,则使用观察者模式,它是一种定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这让我想起了我每个月的车牌摇号,都会推送给我一条本月没中签的消息!!!

二、目标

在 Spring 中有一个Event事件功能,它可以提供事件的定义、发布以及监听事件来完成一些自定义的动作。比如你可以定义一个新用户注册的事件,当有用户执行注册完成后,在事件监听中给用户发送一些优惠券和短信提醒,这样的操作就可以把属于基本功能的注册和对应的策略服务分开,降低系统的耦合。以后在扩展注册服务,比如需要添加风控策略、添加实名认证、判断用户属性等都不会影响到依赖注册成功后执行的动作。

那么在本章节我们需要以观察者模式的方式,设计和实现 Spring Event 的容器事件和事件监听器功能,最终可以让我们在现有实现的Spring框架中可以定义、监听和发布自己的事件信息。

三、方案

其实事件的设计本身就是一种观察者模式的实现,它所要解决的就是一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

在功能实现上我们需要定义出事件类、事件监听、事件发布,而这些类的功能需要结合到 Spring的AbstractApplicationContext#refresh(),以便于处理事件初始化和注册事件监听器的操作。整体设计结构如下图:

  • 在整个功能实现过程中,仍然需要在面向用户的应用上下文 AbstractApplicationContext中添加相关事件内容,包括:初始化事件发布者、注册事件监听器、发布容器刷新完成事件。
  • 使用观察者模式定义事件类、监听类、发布类,同时还需要完成一个广播器的功能,接收到事件推送时进行分析处理符合监听事件接受者感兴趣的事件,也就是使用isAssignableFrom 进行判断。
  • isAssignableFrom 和 instanceof 相似,不过 isAssignableFrom是用来判断子类和父类的关系的,或者接口的实现类和接口的关系的,默认所有的类的终极父类都是Object。如果A.isAssignableFrom(B)结果是true,证明B可以转换成为A,也就是A可以由B转换而来。

四、实现

1. 工程结构

工程源码:公众号「bugstack虫洞栈」,回复:Spring 专栏,获取完整源码

容器事件和事件监听器实现类关系,如图 11-2

图 10-2

  • 以上整个类关系图以围绕实现 event 事件定义、发布、监听功能实现和把事件的相关内容使用AbstractApplicationContext#refresh 进行注册和处理操作。
  • 在实现的过程中主要以扩展 spring context包为主,事件的实现也是在这个包下进行扩展的,当然也可以看出来目前所有的实现内容,仍然是以IOC为主。
  • ApplicationContext 容器继承事件发布功能接口 ApplicationEventPublisher,并在实现类中提供事件监听功能。
  • ApplicationEventMulticaster 接口是注册监听器和发布事件的广播器,提供添加、移除和发布事件方法。
  • 最后是发布容器关闭事件,这个仍然需要扩展到 AbstractApplicationContext#close 方法中,由注册到虚拟机的钩子实现。

2. 定义和实现事件

cn.bugstack.springframework.context.ApplicationEvent

  • 以继承 java.util.EventObject 定义出具备事件功能的抽象类ApplicationEvent,后续所有事件的类都需要继承这个类。

cn.bugstack.springframework.context.event.ApplicationContextEvent

cn.bugstack.springframework.context.event.ContextClosedEvent

cn.bugstack.springframework.context.event.ContextRefreshedEvent

  • ApplicationContextEvent 是定义事件的抽象类,所有的事件包括关闭、刷新,以及用户自己实现的事件,都需要继承这个类。
  • ContextClosedEvent、ContextRefreshedEvent,分别是 Spring框架自己实现的两个事件类,可以用于监听刷新和关闭动作。

3. 事件广播器

cn.bugstack.springframework.context.event.ApplicationEventMulticaster

  • 在事件广播器中定义了添加监听和删除监听的方法以及一个广播事件的方法 multicastEvent最终推送时间消息也会经过这个接口方法来处理谁该接收事件。

cn.bugstack.springframework.context.event.AbstractApplicationEventMulticaster

  • AbstractApplicationEventMulticaster是对事件广播器的公用方法提取,在这个类中可以实现一些基本功能,避免所有直接实现接口放还需要处理细节。
  • 除了像 addApplicationListener、removeApplicationListener,这样的通用方法,这里这个类中主要是对getApplicationListeners 和 supportsEvent 的处理。
  • getApplicationListeners 方法主要是摘取符合广播事件中的监听处理器,具体过滤动作在 supportsEvent 方法中。
  • 在 supportsEvent方法中,主要包括对Cglib、Simple不同实例化需要获取目标Class,Cglib代理类需要获取父类的Class,普通实例化的不需要。接下来就是通过提取接口和对应的ParameterizedType 和eventClassName,方便最后确认是否为子类和父类的关系,以此证明此事件归这个符合的类处理。可以参考代码中的注释

supportsEvent 方法运行截图

  • 在代码调试中可以看到,最终 eventClassName 和 event.getClass() 在 isAssignableFrom 判断下为true
  • 关于 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 可以尝试在AbstractApplicationContext 类中更换验证。

4. 事件发布者的定义和实现

cn.bugstack.springframework.context.ApplicationEventPublisher

  • ApplicationEventPublisher 是整个一个事件的发布接口,所有的事件都需要从这个接口发布出去。

  • 在抽象应用上下文 AbstractApplicationContext#refresh 中,主要新增了初始化事件发布者、注册事件监听器、发布容器刷新完成事件,三个方法用于处理事件操作。

  • 初始化事件发布者(initApplicationEventMulticaster),主要用于实例化一个SimpleApplicationEventMulticaster,这是一个事件广播器。
  • 注册事件监听器(registerListeners),通过 getBeansOfType 方法获取到所有从 spring.xml 中加载到的事件配置Bean 对象。
  • 发布容器刷新完成事件(finishRefresh),发布了第一个服务器启动完成后的事件,这个事件通过 publishEvent 发布出去,其实也就是调用了applicationEventMulticaster.multicastEvent(event); 方法。
  • 最后是一个 close 方法中,新增加了发布一个容器关闭事件。publishEvent(newContextClosedEvent(this));

五、测试

1. 创建一个事件和监听器

cn.bugstack.springframework.test.event.CustomEvent

  • 创建一个自定义事件,在事件类的构造函数中可以添加自己的想要的入参信息。这个事件类最终会被完成的拿到监听里,所以你添加的属性都会被获得到。

cn.bugstack.springframework.test.event.CustomEventListener

  • 这个是一个用于监听 CustomEvent 事件的监听器,这里你可以处理自己想要的操作,比如一些用户注册后发送优惠券和短信通知等。
  • 另外是关于 ContextRefreshedEventListener implementsApplicationListener、ContextClosedEventListener implementsApplicationListener 监听器,这里就不演示了,可以参考下源码。

2. 配置文件

  • 在 spring.xml 中配置了三个事件监听器,监听刷新、监控自定义事件、监听关闭事件。

3. 单元测试

  • 通过使用 applicationContext 新增加的发布事件接口方法,发布一个自定义事件 CustomEvent,并透传了相应的参数信息。

测试结果

  • 从测试结果可以看到,我们自己定义的事件和监听,以及监听系统的事件信息,都可以在控制台完整的输出出来了。你也可以尝试增加一些其他事件行为,并调试代码学习观察者模式。

六、总结

  • 在整个手写 Spring框架的学习过程中,可以逐步看到很多设计模式的使用,比如:简单工厂BeanFactory、工厂方法FactoryBean、策略模式访问资源,现在又实现了一个观察者模式的具体使用。所以学习Spring 的过程中,要更加注意关于设计模式的运用,这是你能读懂代码的核心也是学习的重点。
  • 那么本章节关于观察者模式的实现过程,主要包括了事件的定义、事件的监听和发布事件,发布完成后根据匹配策略,监听器就会收到属于自己的事件内容,并做相应的处理动作,这样的观察者模式其实日常我们也经常使用,不过在结合Spring 以后,除了设计模式的学习,还可以学到如何把相应观察者的实现和应用上下文结合。
  • 所有在 Spring学习到的技术、设计、思路都是可以和实际的业务开发结合起来的,而这些看似比较多的代码模块,其实也是按照各自职责一点点的扩充进去的。在自己的学习过程中,可以先动手尝试完成这些框架功能,在一点点通过调试的方式与Spring 源码进行对照参考,最终也就慢慢掌握这些设计和编码能力了。

推荐系统

  • 微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载

    微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载

    语言:中文版系统大小:5.13GB系统类型:Win11

    微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Win11 64位 Office办公版(免费)优化  1、保留 Edge浏览器。  2、隐藏“操作中心”托盘图标。  3、保留常用组件(微软商店,计算器,图片查看器等)。  5、关闭天气资讯。 

  • Win11 21H2 官方正式版下载_Win11 21H2最新系统免激活下载

    Win11 21H2 官方正式版下载_Win11 21H2最新系统免激活下载

    语言:中文版系统大小:4.75GB系统类型:Win11

    Ghost Win11 21H2是微软在系统方面技术积累雄厚深耕多年,Ghost Win11 21H2系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Ghost Win11 21H2是微软最新发布的KB5019961补丁升级而来的最新版的21H2系统,以Windows 11 21H2 22000 1219 专业版为基础进行优化,保持原汁原味,系统流畅稳定,保留常用组件

  • windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载

    windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载

    语言:中文版系统大小:5.31GB系统类型:Win11

    windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载,微软win11发布快大半年了,其中做了很多次补丁和修复一些BUG,比之前的版本有一些功能上的调整,目前已经升级到最新版本的镜像系统,并且优化了自动激活,永久使用。windows11中文版镜像国内镜像下载地址微软windows11正式版镜像 介绍:1、对函数算法进行了一定程度的简化和优化

  • 微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载

    微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载

    语言:中文版系统大小:5.31GB系统类型:Win11

    微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载,微软2022年正式推出了win11系统,很多人迫不及待的要体验,本站提供了最新版的微软Windows11正式版系统下载,微软windows11正式版镜像 是一款功能超级强大的装机系统,是微软方面全新推出的装机系统,这款系统可以通过pe直接的完成安装,对此系统感兴趣,想要使用的用户们就快来下载

  • 微软windows11系统下载 微软原版 Ghost win11 X64 正式版ISO镜像文件

    微软windows11系统下载 微软原版 Ghost win11 X64 正式版ISO镜像文件

    语言:中文版系统大小:0MB系统类型:Win11

    微软Ghost win11 正式版镜像文件是一款由微软方面推出的优秀全新装机系统,这款系统的新功能非常多,用户们能够在这里体验到最富有人性化的设计等,且全新的柔软界面,看起来非常的舒服~微软Ghost win11 正式版镜像文件介绍:1、与各种硬件设备兼容。 更好地完成用户安装并有效地使用。2、稳定使用蓝屏,系统不再兼容,更能享受无缝的系统服务。3、为

  • 雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载

    雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载

    语言:中文版系统大小:4.75GB系统类型:

    雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业的雨林木风品牌,其系统口碑得到许多人认可,积累了广大的用户群体,雨林木风是一款稳定流畅的系统,一直以来都以用户为中心,是由雨林木风团队推出的Windows11国内镜像版,基于国内用户的习惯,做了系统性能的优化,采用了新的系统

  • 雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO

    雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO

    语言:中文版系统大小:5.91GB系统类型:Win7

    雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO在系统方面技术积累雄厚深耕多年,加固了系统安全策略,雨林木风win7旗舰版系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。win7 32位旗舰装机版 v2019 05能够帮助用户们进行系统的一键安装、快速装机等,系统中的内容全面,能够为广大用户

  • 番茄花园Ghost Win7 x64 SP1稳定装机版2022年7月(64位) 高速下载

    番茄花园Ghost Win7 x64 SP1稳定装机版2022年7月(64位) 高速下载

    语言:中文版系统大小:3.91GB系统类型:Win7

    欢迎使用 番茄花园 Ghost Win7 x64 SP1 2022.07 极速装机版 专业装机版具有更安全、更稳定、更人性化等特点。集成最常用的装机软件,集成最全面的硬件驱动,精心挑选的系统维护工具,加上独有人性化的设计。是电脑城、个人、公司快速装机之首选!拥有此系统