Spring的事件(Application Event)为Bean与Bean之间的信息通讯提供了支持。当一个Bean处理完一个任务之后,希望另一Bean指定并能做相应的处理,这时我们就需要让另外一个Bean监听当期Bean所发送的事件。

  通过上述基本信息可知,Spring的事件需要遵循如下流程:

    (1) 自定义事件,继承ApplicationEvent;

    (2)定义事件监听器,实现ApplicationListener;

    (3)使用容器发布事件。

  可以理解以上的流程就是Spring默认的事件生效规范。

  下面简单举例上述规范:

    1、自定义事件

      

    2、事件监听器

      

    3、事件发布

      

    4、配置

      

    5、运行

      

  测试结果如下:

    

  上例中,在事件发布和实际应用运行中都是用到了容器ApplicationContext,这是两个不同的容器其作用也不一样:前者用于事件发布,后者用于bean的装载。通过此例同时验证了spring的功能不仅仅类似装水的容器单一功能,该容器还附带其他功能。就如可以放音乐的冰箱,冰箱本身的功能是保存食物,但是不妨碍制造者制造冰箱时提供其基本功能以外的其他功能。

  此例中的其他功能Bean之间消息传递使用的Application Event是如何有效工作的呢?上述源码中没有调用事件监听类的迹象,但是实际运行结果确实打印处理监听类中的信息。这里就得从命令设计模式的角度去理解了,实际这只是个人的理解,从理论的角度严格说来具体是否是命令模式待商榷吧(个人理论水平有限)。

  其UML图如下:

    

  看似与命令模式没有关联,实际情况是此例中使用的接口都是Spring封装好的,在此图中无法体现。如果将Spring封装好的接口在UML中体现,将是怎样的呢?

     

  上图与命令模式的UML图也不尽相同。上图Event作为参数将整个UML图形成一个C型环,而命令模式通过命令接口作为一个对象实现C型环。但是为什么还是可以按照命令模式的逻辑理解呢?因为它们有个共同点:就是发布指令,与执行指令完全没有任何直接的联系。发布指令后,如果不跟踪根本不知道这个指令是怎么执行的——执行过程对外完全屏蔽。对于用户而言,只需发布指令即可,接收者或者监听者无论发生什么变化用户是不可知的;对开发者而言,如果业务发生改变,改变执行该业务接收者或监听者即可。

  跟踪发现:在Spring中,prepareBeanFactory时,处理Publisher相关内容;Listener创建时,后置处理器,处理监听器的添加;执行具体发布指令的命令时触发监听者执行相关的指令:

    

  所以,实际上Spring将指令的实际执行者封装在了容器中,而不是如通用的命令模式将Receiver封装在具体的命令中。而ApplicationContext本身就是一个publisher:

    

  即ApplicationContext进行事件发布时之前,该事件监听者已经进行了注册并与其形参一对多的关系,只待调用:

    

从命令模式的维度理解Spring 之Application Event的更多相关文章

  1. spring 事件(Application Event)

    spring 事件为bean 与 bean之间传递消息.一个bean处理完了希望其余一个接着处理.这时我们就需要其余的一个bean监听当前bean所发送的事件. spring事件使用步骤如下: 1.先 ...

  2. Head First 设计模式 --6 命令模式

    命令模式:将"请求"封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象.命令模式也支持可撤销的操作.用到的原则:1.封装变化2.组合优于继承3.针对接口编程,不能针对实现 ...

  3. Java设计模式-命令模式(Command)

    命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不用去依赖其 ...

  4. 命令模式(Command)

    命令模式(Command) 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互 ...

  5. 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)

    1 智能生活项目需求 看一个具体的需求 1) 我们买了一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装 app 就可以控制对这些家电工作. 2) 这些智能家电来自不同的厂家,我们不想针 ...

  6. 设计模式学习笔记(十五)命令模式及在Spring JdbcTemplate 中的实现

    命令(Command)模式是指将请求封装成为一个对象,使发出请求和执行请求的责任分割开,方便将命令对象进行存储.传递.调用.增加与管理. 也就是将发送者.接收者和调用命令封装成独立的对象,来供客户端调 ...

  7. Spring IOC 方式结合TESTGN测试用例,测试简单java的命令模式

    java命令模式: 可以命令("请求")封装成一个对象,一个命令对象通过在特定的接收着上绑定一组动作来封装一个请求.命令对象直接把执行动作和接收者包进对象中,只对外暴露出执行方法的 ...

  8. 深入理解JavaScript系列(34):设计模式之命令模式

    介绍 命令模式(Command)的定义是:用于将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或者记录请求日志,以及执行可撤销的操作.也就是说改模式旨在将函数的调用.请求和 ...

  9. JS命令模式个人理解

    JS命令模式个人理解 //BODY部分<body> <button id="execute">打开电视</button> <button ...

随机推荐

  1. SYCOJ1793

    题目-统计单词前缀数 (shiyancang.cn) 1 #include<bits/stdc++.h> 2 using namespace std; 3 map<string,in ...

  2. Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401开发

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  3. Idea操作Maven详细使用:

    Idea操作Maven详细使用: Maven简介 什么是 Maven Maven 的正确发音是[ˈmevən] "卖v",而不是"马瘟"以及其他什么瘟. Mav ...

  4. Solon 开发,四、Bean 扫描的三种方式

    Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...

  5. python环境搭建以及jupyter notebook的安装和启动

    一.Python 环境搭建 本章节我们将向大家介绍如何在本地搭建Python开发环境. Python可应用于多平台包括 Linux 和 Mac OS X. 你可以通过终端窗口输入 "pyth ...

  6. [Windows]为windows系统鼠标右键添加软件和图标

    转载自 https://blog.csdn.net/p312011150/article/details/81207059 一.打开注册表 首先打开windows的注册表,当然了,我个人倾向于 (1) ...

  7. java输入年份和月份,输出天数

    import java.util.*; public class Demo { public static void main(String[] args){ int days = 0; Scanne ...

  8. Kubernetes 证书默认1年过期时间修改

    使用过的kubeadm搭建K8s集群的朋友知道,默认自动生成的证书有效期只有 1 年,因此需要每年手动更新一次证书,这种形式显然对实际生产环境来说很不友好:因此下面教给大家修改这个过期时间的终极方法. ...

  9. c++14新特性

    1.函数返回值类型推导 c++14对函数返回类型推导规则做了优化: auto func(int i) { //C++11编译非法,c++14支持auto返回值类型推导 return i; } int ...

  10. Java的代理机制

    Java的代理机制 使用代理 Proxzy 可以在运行时创建一组给定接口的新类,这种功能只有在编译时无法确定需要实现哪种接口时才需要使用. 1. 使用代理的时机 假如有一个表示接口的 Class 对象 ...