扒去Spring事件监听机制的外衣,竟然是观察者模式

本文深入探讨了Spring事件监听机制,它基于观察者模式并结合Java事件机制,允许开发者实现自定义事件监听。文章通过具体代码示例介绍了观察者模式的角色、Java事件的三个角色以及Spring事件的三个组成部分。最后,文章展示了如何在Spring中创建自定义事件和监听器,并讨论了同步与异步事件处理。通过本文,读者能理解Spring事件监听的原理和实践应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Spring中提供了一套默认的事件监听机制,在容器初始化时便使用了这套机制。同时,Spring也提供了事件监听机制的接口扩展能力,开发者基于此可快速实现自定义的事件监听功能。

Spring的事件监听机制是在JDK事件监听的基础上进行的扩展,也是在典型观察者模式上的进一步抽象和改进。所以,结合Spring的事件监听机制与观察者模式来学习,可以达到理论与实践的完美融合。

本篇文章就以观察者模式和Spring事件监听机制作为切入点,结合具体的实例来对两者进行系统的学习和实践。

观察者模式

观察者模式(Observer Pattern),也叫作发布-订阅模式(Publish/Subscribe)。

无论是观察者模式,还是Spring的事件监听机制,本质上都是在定义对象间一对多的依赖关系,使得每当一个对象(被观察者/事件)改变状态时,所有依赖于它的对象(观察者/事件监听器)都会得到通知,并被自动更新。

观察者模式的优点在于:观察者和被观察者之间是抽象耦合,不管是新增观察者或是被观察者,都非常容易扩展。这也符合面向对象所倡导的“开闭原则”:对扩展开放,对修改关闭

观察者模式适用于以下三类场景:

  • 关联行为场景,而且关联是可拆分的。

  • 事件多级触发场景。

  • 跨系统的消息交换场景,比如消息队列的处理机制。

在使用的过程中,也要综合考虑开发效率和运行效率的问题。通常,一个被观察者会对应多个观察者,那么在开发和调试的过程中会有一定的复杂度。

同时,因为被观察者存在关联、多级拆分,也就是会有多个观察者,而Java消息的通知(和Spring的事件监听机制)默认是顺序执行的,如果其中一个观察者执行时间过长或卡死,势必会影响整体的效率。此时,就需要考虑异步处理。

观察者的角色定义

观察者模式是一个典型的发布-订阅模型,其中主要涉及四个角色:

  • 抽象被观察者角色:内部持有所有观察者角色的引用,并对外提供新增、移除观察者角色、通知所有观察者的功能;

  • 具体被观察者角色:当状态变更时,会通知到所有的观察者角色;

  • 抽象观察者角色:抽象具体观察者角色的一些共性方法,如状态变更方法;

  • 具体观察者角色:实现抽象观察者角色的方法;

UML类图展示类观察者模式大体如下:

观察者模式类图

以具体的代码来展示一下观察者模式的实现。

第一,定义抽象观察者。

/**
 * 抽象观察者角色
 * @author sec
 **/
public abstract class AbstractObserver {

 /**
  * 接收消息
  * @param context 消息内容
  */
 public abstract void receiveMsg(String context);

}

第二,定义抽象被观察者。

/**
 * 抽象主题(抽象被观察者角色)
 * @author sec
 **/
public abstract class AbstractSubject {

 /**
  * 持有所有抽象观察者角色的集合引用
  */
 private final List<AbstractObserver> observers = new ArrayList<>();

 /**
  * 添加一个观察者
  * @param observer 观察者
  */
 public void addObserver(AbstractObserver observer){
  observers.add(observer);
 }

 /**
  * 移除一个观察者
  * @param observer 观察者
  */
 public void removeObserver(AbstractObserver observer){
  observers.remove(observer);
 }

 /**
  * 通知所有的观察者,执行观察者更新方法
  * @param context 通知内容
  */
 public void notifyObserver(String context){
  observers.forEach(observer -> observer.receiveMsg(context));
 }
}

第三,定义具体被观察者,实现了抽象被观察者。

/**
 * 具体被观察者
 * @author sec
 **/
public class ConcreteSubj
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值