Spring基于事件驱动模型的订阅发布模式代码实例详解
转载地址:http://blog.****.net/yaerfeng/article/details/27683813
Spring提供的事件驱动模型/观察者抽象
首先看一下Spring提供的事件驱动模型体系图:
事件
具体代表者是:ApplicationEvent:
1、其继承自JDK的EventObject,JDK要求所有事件将继承它,并通过source得到事件源,比如我们的AWT事件体系也是继承自它;
2、系统默认提供了如下ApplicationEvent事件实现:
只有一个ApplicationContextEvent,表示ApplicationContext容器事件,且其又有如下实现:
- ContextStartedEvent:ApplicationContext启动后触发的事件;(目前版本没有任何作用)
- ContextStoppedEvent:ApplicationContext停止后触发的事件;(目前版本没有任何作用)
- ContextRefreshedEvent:ApplicationContext初始化或刷新完成后触发的事件;(容器初始化完成后调用)
- ContextClosedEvent:ApplicationContext关闭后触发的事件;(如web容器关闭时自动会触发spring容器的关闭,如果是普通java应用,需要调用ctx.registerShutdownHook();注册虚拟机关闭时的钩子才行)
注:org.springframework.context.support.AbstractApplicationContext抽象类实现了LifeCycle的start和stop回调并发布ContextStartedEvent和ContextStoppedEvent事件;但是无任何实现调用它,所以目前无任何作用。
目标(发布事件者)
具体代表者是:ApplicationEventPublisher及ApplicationEventMulticaster,系统默认提供了如下实现:
1、ApplicationContext接口继承了ApplicationEventPublisher,并在AbstractApplicationContext实现了具体代码,实际执行是委托给ApplicationEventMulticaster(可以认为是多播):
Java代码
我们常用的ApplicationContext都继承自AbstractApplicationContext,如ClassPathXmlApplicationContext、XmlWebApplicationContext等。所以自动拥有这个功能。
2、ApplicationContext自动到本地容器里找一个名字为”“的ApplicationEventMulticaster实现,如果没有自己new一个SimpleApplicationEventMulticaster。其中SimpleApplicationEventMulticaster发布事件的代码如下:
Java代码
大家可以看到如果给它一个executor(java.util.concurrent.Executor),它就可以异步支持发布事件了。佛则就是通过发送。
所以我们发送事件只需要通过ApplicationContext.publishEvent即可,没必要再创建自己的实现了。除非有必要。
监听器
具体代表者是:ApplicationListener
1、其继承自JDK的EventListener,JDK要求所有监听器将继承它,比如我们的AWT事件体系也是继承自它;
2、ApplicationListener接口:
Java代码
其只提供了onApplicationEvent方法,我们需要在该方法实现内部判断事件类型来处理,也没有提供按顺序触发监听器的语义,所以Spring提供了另一个接口,SmartApplicationListener:
Java代码
该接口可方便实现去判断支持的事件类型、目标类型,及执行顺序。
Spring事件机制的简单例子
本例子模拟一个给多个人发送内容(类似于报纸新闻)的例子。
1、定义事件
Java代码
非常简单,如果用户发送内容,只需要通过构造器传入内容,然后通过getSource即可获取。
2、定义无序监听器
之所以说无序,类似于AOP机制,顺序是无法确定的。
Java代码
1、使用@Compoent注册Bean即可;
2、在实现中需要判断event类型是ContentEvent才可以处理;
更简单的办法是通过泛型指定类型,如下所示
Java代码
3、定义有序监听器
实现SmartApplicationListener接口即可。
Java代码
Java代码
- supportsEventType:用于指定支持的事件类型,只有支持的才调用onApplicationEvent;
- supportsSourceType:支持的目标类型,只有支持的才调用onApplicationEvent;
- getOrder:即顺序,越小优先级越高
4、测试
4.1、配置文件
Java代码
就一句话,自动扫描注解Bean。
4.2、测试类
Java代码
接着会输出:
Java代码
一个简单的测试例子就演示完毕,而且我们使用spring的事件机制去写相关代码会非常简单。