基于Spring的发布订阅模式在我们使用spring开发应用时 , 经常会碰到要去解耦合一些依赖调用 , 比如我们在做代码的发布流程中 , 需要去通知相关的测试 , 开发人员关注发布中的错误信息 。而且通知这个操作又不希望强耦合在主业务流程中 , 这个时候我们很容易就想到了观察者设计模式 , 而spring恰好提供了事件-监听机制 , 让我们看一下他们是具体怎么实现的吧 。
事件-监听机制:
- 首先是一种对象间的一对多的关系;最简单的如交通信号灯 , 信号灯是目标(一方) , 行人注视着信号灯(多方);
- 当目标发送改变(发布) , 观察者(订阅者)就可以接收到改变;
- 观察者如何处理(如行人如何走 , 是快走/慢走/不走 , 目标不会管的) , 目标无需干涉;所以就松散耦合了它们之间的关系 。
![基于Spring的发布订阅模式 EventListener](http://shimg.jingyanzongjie.com/230728/05124H254-0.png)
文章插图
其实整个模型就有三个角色 , 事件 , 目标(发布者) , 监听者 , 我们看一下spring中如何实现这三者
事件:【基于Spring的发布订阅模式 EventListener】具体代表者是:ApplicationEvent:
1、 我们可以看到spring中ApplicationEvent该抽象类继承自JDK的EventObject 。JDK要求所有事件将继承它 , 并通过source得到事件源 。
package org.springframework.context;import java.util.EventObject;/** * Class to be extended by all application events. Abstract as it * doesn't make sense for generic events to be published directly. * * @author Rod Johnson * @author Juergen Hoeller */public abstract class ApplicationEvent extends EventObject { /** use serialVersionUID from Spring 1.2 for interoperability */ private static final long serialVersionUID = 7099057708183571937L; /** System time when the event happened */ private final long timestamp; /*** Create a new ApplicationEvent.* @param source the object on which the event initially occurred (never {@code null})*/ public ApplicationEvent(Object source) {super(source);this.timestamp = System.currentTimeMillis(); } /*** Return the system time in milliseconds when the event happened.*/ public final long getTimestamp() {return this.timestamp; }}
目标(发布者)具体代表者是具体代表者是:ApplicationEventPublisher及ApplicationEventMulticaster 。ApplicationContext该接口继承了ApplicationEventPublisher , 并在AbstractApplicationContext实现了具体代码 , 实际执行是委托给ApplicationEventMulticaster(可以认为是多播):
ApplicationContext继承自ApplicationEventPublisher
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}ApplicationEventPublisher定义了publishEvent方法
public interface ApplicationEventPublisher {/*** Notify all <strong>matching</strong> listeners registered with this* application of an application event. Events may be framework events* (such as RequestHandledEvent) or application-specific events.* @param event the event to publish* @see org.springframework.web.context.support.RequestHandledEvent*/void publishEvent(ApplicationEvent event);/*** Notify all <strong>matching</strong> listeners registered with this* application of an event.* <p>If the specified {@code event} is not an {@link ApplicationEvent},* it is wrapped in a {@link PayloadApplicationEvent}.* @param event the event to publish* @since 4.2* @see PayloadApplicationEvent*/void publishEvent(Object event);}在AbstractApplicationContext实现了具体代码,实际执行是委托给ApplicationEventMulticaster(可以认为是多播)
经验总结扩展阅读
- 金牛座的爱真的长久吗
- 12星座谁爱起来最疯狂、最高调
- 记一次多个Java Agent同时使用的类增强冲突问题及分析
- 十二星座爱情走不到终点的原因
- 怎样蒸螃蟹
- 超市买的米酒怎么吃啊
- 12星座女孩子久经情场的必杀技
- 螃蟹的热量
- 卤肉两三天不变色的方法
- 爱情渐渐离去选择默默离开的星座