观察者模式、监听器以及Spring中的监听器
发布日期:2021-05-18 13:24:59 浏览次数:13 分类:精选文章

本文共 1933 字,大约阅读时间需要 6 分钟。

观察者模式与Spring事件监听机制的深度比较

在软件开发中,确保系统各组件之间的良好通信是设计中的关键环节。观察者模式和 listening pattern(以下简称 "监听器模式")是解决这一问题的两大不同设计模式。尽管两者在底层机制上存在差异,但是理解其异同点对于选择合适的解决方案至关重要。本文将从概念到实践,全面探讨这两种模式的应用场景及其在Spring框架中的表现。

观察者模式

观察者模式(Observer Pattern)是一种设计模式,核心思想是被观察者(subject)与多个观察者(observer)之间建立动态的关系。一旦被观察者发生特定行为,会自动通知所有关注的观察者,让它们做出相应的响应。

角色角色分工
  • 抽象观察者 (IObserver):定义了观察者对被观察者行为的响应方式。
  • 抽象被观察者 (ISubject):维护观察者队列,并通知所有观察者。
  • 具体观察者 (ConcreteObserver):实现了抽象观察者接口,对具体事件做出响应。
  • 具体被观察者 (ConcreteSubject):实现了抽象被观察者的方法,完成具体业务并通知所有观察者。
实现机制
  • 对于一个典型的.get().work()流程,具体被观察者将在自身业务完成后调用notifyObervers()方法。
  • 具体被观察者的 notifyObervers() 方法会遍历观察者队列,将每个观察者的 action() 方法叫醒。
  • 观察者可以通过自己的注册方法 (@register) 将自身添加到被观察者的队列中。
  • 应用案例

    为简化理解,我们可以用一个Twitter-like的例子:“用户发布微博”——用户是被观察者,关注的是其他用户发布的微博内容,微博发布是被观察者的行为。

    监听器模式

    listening pattern("监听器模式")虽然在概念上与观察者模式类似,但其背后的机制有所不同。观察者模式与 listening pattern 的主要区别是事件传递的内容:观察者模式传递行为, listening pattern 传递行为+事件实例。

    角色角色分工
    • 事件源 (Event Source):生成事件实例。
    • 事件对象 (Event):包含事件类型和事件源信息。
    • 事件监听器 (Listener):定义对特定事件的响应方式。
    实现机制
  • 事件源触发特定方法(如sendNotification())发布事件。
  • 事件对象保留事件类型和源信息,便于监听器分析处理。
  • 每个事件类型可能对应不同的队列,缩小事件监听的粒度。
  • 与观察者模式的区别
    • 事件对象传递:在观察者模式中,传递的是行为,而非行为+事件实例。
    • 响应灵活性:在 listening pattern 中,监听器可以根据事件类型自行决定如何处理,没有强制性约束。

    观察者模式与 listening pattern 的关系

    两种模式在运行机制上有直接的关联:观察者模式可被视为 listening pattern 的一种特例,只是不传递事件对象。

    Spring中的事件监听机制

    在Spring框架中,应用 ProgramaticListener 和 lắng leser模式结合使用,提供更灵活的事件管理机制。

    • ApplicationEvent:定义了基本的事件类,继承自Spring提供的EventObject。
    • ApplicationListener:定义了对事件做出的响应方式,通常通过接口定义。
    • ApplicationContext:作为事件发布者的核心接口,提供事件发布和处理的基础支持。
    事件监听的实现方式
  • 注解方式
    @componentpublic class MyAnnotationListener implements ApplicationListenercuritiesevent> {    @EventListener    public void handle(SecuritiesEvent event) {        // 自定义处理逻辑    }}
  • 手动注册方式
    appContext.addListener(new MyListener() {    @Override    public void onApplicationEvent(ApplicationEvent event) {        // 定义的事件响应逻辑    }});
  • 常见问题与优化

    在实际应用中,一个常见的难点是如何管理 listener 的生命周期和依赖注入。例如,当使用非Spring管理的 listener 实例进行操作时,需要特别注意ServletContextリス

    上一篇:关于Spring与SpringMVC父子容器及扫描包的问题
    下一篇:关于http请求传参的总结

    发表评论

    最新留言

    很好
    [***.229.124.182]2025年04月27日 17时38分46秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章

    ddr2的上电顺序_S5PV210 DDR2初始化 28个步骤总结 2023-01-24
    deque stack java_「集合系列」- 初探 java 集合框架图 2023-01-24
    easyexcel 导出 代码翻译converter_【starter推荐】简单高效Excel 导出工具 2023-01-24
    echarts 如何在一条柱形显示两个数字_干货 | 如何快速制作数据地图?让你的可视化逼格再高一级!... 2023-01-24
    eclipse设置utf8编码_记住没:永远不要在 MySQL 中使用 UTF8 2023-01-24
    eclipse里source的快捷方法_Eclipse快捷键/快捷操作汇总 2023-01-24
    elasticsearch 查询_Elasticsearch地理信息存储及查询之Geo_Point 2023-01-24
    embedding层_【预估排序】Embedding+MLP: 深度学习预估排序通用框架(一) 2023-01-24
    excel中最常用的30个函数_Excel玩转数据分析常用的43个函数! 2023-01-24
    flink sql设置并行度_Flink 参数配置和常见参数调优 2023-01-24
    go 字符串替换_Go 每日一库之 quicktemplate 2023-01-24
    hex editor neo下载_口袋妖怪爆焰黑手机版下载-口袋妖怪爆焰黑手游下载v4.3.0 安卓版... 2023-01-24
    hibernate mysql 关联查询_spring-boot hibernate 双向关联查询的坑 2023-01-24
    hive 建表_sqoop的使用之导入到hive和mysql 2023-01-24
    hp工作站z8装Linux,惠普Z8G4双路最小工作站 2023-01-24
    html上传图片直接保存到数据库中,Editor上传图片路径存入数据库中怎么弄? 2023-01-24
    html游戏玩不了,WinXP网页游戏玩不了怎么办有哪些解决方法 2023-01-24
    html转jsp_JSP详解 2023-01-24
    ICLOUD储存空间要升级吗_有人像我一样需要恢复苹果手机icloud空间ios备份时 微信卡住不动了吗(已解决)... 2023-01-24
    image unity 原始尺寸_Unity基础教程-对象管理(十一)——生命周期(Growth and Death)... 2023-01-24