当前位置: 首页 > news >正文

监听者的力量:探索观察者模式和spring使用

观察者模式是一种对象行为型设计模式,它定义了对象之间的一对多依赖关系。
观察者模式通常用于实现分布式事件处理系统、新闻代理或MVC框架的一部分。在这种模式中,一个对象(称为“主题”或“可观察对象”)维护一系列依赖于它的对象(称为“观察者”),并在其状态发生变化时自动通知所有观察者。这种模式的主要目的是确保观察者对象在主题对象的状态改变时得到更新。

观察者模式-java实现

import java.util.Observable;
import java.util.Observer;public class ObserverPatternDemo {public static void main(String[] args){Subject subject = new Subject();new BinaryObserver(subject);new OctalObserver(subject);new HexaObserver(subject);System.out.println("First state change: 15");subject.setState(15);System.out.println("Second state change: 10");subject.setState(10);}
}class Subject extends Observable {private int state;public int getState() {return state;}public void setState(int state) {this.state = state;setChanged();notifyObservers();}
}class BinaryObserver implements Observer {public BinaryObserver(Subject subject) {subject.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {System.out.println("Binary String: " + Integer.toBinaryString(((Subject) o).getState()));}
}class OctalObserver implements Observer {public OctalObserver(Subject subject) {subject.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {System.out.println("Octal String: " + Integer.toOctalString(((Subject) o).getState()));}
}class HexaObserver implements Observer {public HexaObserver(Subject subject) {subject.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {System.out.println("Hex String: " + Integer.toHexString(((Subject) o).getState()).toUpperCase());}
}

在这个例子中,我们创建了一个Subject类,它继承了Java内置的Observable类,并且在Subject类中定义了一个状态state。当Subject类的状态发生改变时,会调用setChanged()方法和notifyObservers()方法来通知观察者。BinaryObserver、OctalObserver和HexaObserver是观察者类,它们在构造函数中注册到Subject类中。当Subject类的状态发生改变时,它们会接收到通知并且自动更新。

Spring的事件机制的基本概念

Spring的事件机制是Spring框架中的一个重要特性,基于观察者模式实现,它可以实现应用程序中的解耦,提高代码的可维护性和可扩展性。Spring的事件机制包括事件、事件发布、事件监听器等几个基本概念。其中,事件是一个抽象的概念,它代表着应用程序中的某个动作或状态的发生。事件发布是事件发生的地方,它负责产生事件并通知事件监听器。事件监听器是事件的接收者,它负责处理事件并执行相应的操作。在Spring的事件机制中,事件源和事件监听器之间通过事件进行通信,从而实现了模块之间的解耦。以下是使用方法:

  • 通过继承ApplicationEvent,实现自定义事件。是对 Java EventObject 的扩展,表示 Spring 的事件,Spring 中的所有事件都要基于其进行扩展。
public class MyEvent extends ApplicationEvent {private String name;public MyEvent(Object source, String name) {super(source);this.name = name;}@Overridepublic String toString() {return "MyEvent{" +"name='" + name + '\'' +"} " + super.toString();}
}
  • 接下来通过事件发布器将事件发布出去。Spring 中事件发布器有专门的接口 ApplicationEventPublisher:
public interface ApplicationEventPublisher {default void publishEvent(ApplicationEvent event) {publishEvent((Object) event);}void publishEvent(Object event);
}
  • 事件发布方式如下:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
ctx.publishEvent(new MyEvent(new Demo(), "javaboy"));
  • 实现监听器,事件监听器有两种定义方式。
  1. 实现接口
@Component
public class MyEventListener implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {System.out.println("event = " + event);}
}
  1. 注解:
@Component
public class MyEventListener {@EventListener(value = MyEvent.class)public void hello(MyEvent event) {System.out.println("event02 = " + event);}
}

Spring框架的事件处理机制适用场景

  1. 业务状态变化通知:当应用程序中的某个业务状态发生变化时,可以通过Spring事件机制通知所有感兴趣的组件。例如,用户注册成功后,可以发布一个事件通知其他系统进行相应的处理,如发送欢迎邮件、更新用户统计信息等。
  2. 异步消息处理:在需要处理大量数据或执行耗时操作时,可以利用事件机制进行异步处理。这样可以避免阻塞主线程,提高系统的响应速度和吞吐量。
  3. 组件间的松耦合通信:Spring事件机制允许不同的组件之间进行通信而不需要直接依赖对方。这种松耦合的设计使得组件可以独立地开发、测试和部署,有助于提高系统的整体稳定性。
  4. 插件式架构支持:对于需要支持插件或模块扩展的应用程序,事件机制提供了一个标准化的方式来让插件参与到主程序的运行流程中,而无需修改主程序的代码。
  5. 系统集成与扩展:在进行系统集成或添加新功能时,事件机制可以作为一种灵活的扩展手段,通过定义新的事件和监听器来集成外部服务或增加新的业务逻辑。
  6. 错误处理与监控:在应用程序运行过程中,可能会遇到各种错误或异常情况。通过事件机制,可以将错误信息封装成事件并发布,然后由专门的错误处理组件来监听和处理这些事件,从而实现集中式的错误处理和监控。
  7. 跨服务通信:在微服务架构中,不同服务之间可以通过事件机制来进行通信,实现服务的解耦和灵活交互。

相关文章:

  • [NOIP2007 普及组] 纪念品分组--贪心算法
  • 论文里点击如图?-?如何跳转到图片的题注
  • 探秘SpringBoot启动流程:原理解析与自定义扩展
  • Mongodb基础(node.js版)
  • C2_W2_Assignment_吴恩达_中英_Pytorch
  • 【简略知识】项目开发中,VO,BO,PO,DO,DTO究竟是何方妖怪?
  • 腾讯云幻兽帕鲁服务器如何安全下载WorldOption.sav文件?
  • 抖音视频批量下载软件|视频评论采集工具
  • 开源视频转码器HandBrake
  • Godot自定义控件样式语法解析
  • Java数据类型(八种基本数据类型 + 四种引用类型)、数据类型转换
  • 机器学习:模型评估和模型保存
  • 【软考】设计模式之访问者模式
  • Redis的主从搭建
  • Linux笔记--GCC
  • Angular6错误 Service: No provider for Renderer2
  • C++11: atomic 头文件
  • CentOS 7 防火墙操作
  • HTTP中GET与POST的区别 99%的错误认识
  • JavaScript 奇技淫巧
  • javascript 总结(常用工具类的封装)
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • JS字符串转数字方法总结
  • Mysql优化
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • 动态规划入门(以爬楼梯为例)
  • 动态魔术使用DBMS_SQL
  • 对超线程几个不同角度的解释
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 想写好前端,先练好内功
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 鱼骨图 - 如何绘制?
  • JavaScript 新语法详解:Class 的私有属性与私有方法 ...
  • PostgreSQL之连接数修改
  • puppet连载22:define用法
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 我们雇佣了一只大猴子...
  • # Apache SeaTunnel 究竟是什么?
  • (3)llvm ir转换过程
  • (ZT)一个美国文科博士的YardLife
  • (差分)胡桃爱原石
  • (汇总)os模块以及shutil模块对文件的操作
  • (转)fock函数详解
  • (转)http协议
  • .equals()到底是什么意思?
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .Net Remoting常用部署结构
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .net快速开发框架源码分享
  • .NET学习教程二——.net基础定义+VS常用设置
  • @private @protected @public
  • [ 云计算 | AWS 实践 ] 基于 Amazon S3 协议搭建个人云存储服务