KOI技术-事件驱动编程(Sping后端)

请添加图片描述

1 “你日渐平庸,甘于平庸,将继续平庸。”——《以自己喜欢的方式过一生》
2. “总是有人要赢的,那为什么不能是我呢?”——科比·布莱恩特
3. “你那么憎恨那些人,和他们斗了那么久,最终却要变得和他们一样,人世间没有任何理想值得以这样的沉沦作为代价。”——马尔克斯《百年孤独》
4. “如果结果不如你所愿,就在尘埃落定前奋力一搏。”——《夏目友人帐》
5. “人有逆天之时,天无绝人之路。”——《醒世恒言》
6. “有些事不是看到了希望才去坚持,而是因为坚持才会看到希望。”——《十宗罪》
7. “维持现状意味着空耗你的努力和生命。”——纪伯伦

Spring * 事件驱动编程

推荐

KOI技术-事件驱动编程(前端)

一. 概念

事件驱动编程是面向事件的,不同于传统的基于顺序的编程,它旨在当事件发生时,再采用行动进行处理的一种编程范式。它使得程序以松耦合的方式进行粘合,实现部分解耦。

二. 主要解决的问题

1.代码的松耦合

将系统复杂的功能拆分为多个部分,每个部分抽象为一个组件,组件与组件之间通过良好定义的接口进行通信;那么他们之间通信的触发若采用引入(依赖)调用的方式,便使得类之间产生了强关系,属于功能耦合,若把他们之间调用的触发抽象为事件,就能降低、解除组件之间的耦合关系。

事件驱动模型,实际上是将组件之间的耦合关系转移到了“事件(Event)”上,但是对于某个领域而言事件(Event)一般具有通用性并且不会频繁变更实现逻辑,所以事件驱动模型可以很好地实现组件之间的解耦。

2.异步编程的需要(MQ 主要用于分布式)

业务场景中,顺序、阻塞式地执行任务会遇到一些比较耗时的中间步骤,但是不希望整个流程都停下来等待这些中间步骤完成,而是触发一个异步操作然后继续执行当前任务,在收到异步操作处理完成的消息之后再执行相关的处理。

使用事件驱动模型实现异步任务的一般思路是:当遇到耗时较大、没有同步执行要求的操作时,针对这个操作触发一个事件,将这个事件加入到任务队列中,直到有一个进程(线程)能够获取并执行这个任务,才开始执行这个任务。

这里大家可能会想到MQ,MQ不就是干这个的吗,对,它确实是做这个的,但是是想一下,我就是一个单机系统或者我是一个底层编程框架,为了实现解耦异步我就要引入MQ,是不是有点大材小用,强制上车的意思。所以:事件编程适用于小范围或者小场景需求,但在框架编程中大量使用。

3.状态模型(状态机,日志记录)

这个场景理解起来比较简单,但是处理这种场景的方式却很多。 比如我们需要对实体状态的变更进行监控,(有没有想到禅道-项目管理中的最新动态),对请求的接口做一些日志记录,但日志有可能需要异步。这里大家可能会联想到AOP,确实在状态监控的实现上考虑到的简单方式就是切面变成,这里是想告诉大家,除了切面,事件驱动也可以实现。各有优劣。

三. 设计模式?

可能大家在查询资料或者学习过程中,会看到,事件编程或者状态管理时,会碰到设计模式中的 “观察者模式”,确实这个模式“很符合”这个场景,那问题来了,需要了解他吗? 我的建议是需要,为啥?懂了它,手写一个高大上的模式在项目上,岂不是更好,对于理解底层架构来说,也提供了思路,岂不更好。

观察者模式是使用频率较高的设计模式之一。 定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。是一种对象行为型模式。

观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。 看到这些名称有没有想到技术上的一些概念?MQ MVVM HODOOP 监听器
在这里插入图片描述
一些概念:

  • Subject(目标):被观察者,它是指被观察的对象。

  • ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知。

  • Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法
    update(),因此又称为抽象观察者。

  • ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer
    中定义的 update()方法。

在这里插入图片描述
图中涉及UML的关系要理解,图比较重要,看的懂才可以继续。:关联(实线实心箭头)泛化(继承 实线空心)实现(虚线空心)聚合(关联关系的一种,实现空心菱形)

四. JDK中的观察者模式(如何自行实现,不是从0开始)

观察者模式在 Java 语言中的地位非常重要。在 JDK 的 java.util 包中,提供了 Observable 类以及 Observer 接口,它们构成了 JDK 对观察者模式的支持(可以去查看下源码,写的比较严谨)。

这种方式不建议使用了,因为在jdk9之后废弃,且存在线程不安全问题,

**(推荐)**java.util.concurrent包中的ConcurrentHashMap和CopyOnWriteArrayList,以及java.util.EventListener相关的API来构建自己的观察者模式实现

五. Spring 的事件驱动编程(正文开始)

1. 概念

  • 事件:ApplicationEvent 是所有事件对象的父类。ApplicationEvent 继承自 jdk 的 EventObject, 所有的事件都需要继承 ApplicationEvent, 并且通过 source 得到事件源。
    Spring 也为我们提供了很多内置事件,ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、ContextClosedEvent、RequestHandledEvent。
  • 事件监听:ApplicationListener,也就是观察者,继承自 jdk 的 EventListener,该类中只有一个方法
    onApplicationEvent。当监听的事件发生后该方法会被执行。
  • 事件源:ApplicationContext,ApplicationContext 是 Spring 中的核心容器,在事件监听中
    ApplicationContext 可以作为事件的发布者,也就是事件源。因为 ApplicationContext 继承自
    ApplicationEventPublisher。在 ApplicationEventPublisher
    中定义了事件发布的方法:publishEvent(Object event)
  • 事件管理:ApplicationEventMulticaster,用于事件监听器的注册和事件的广播。监听器的注册就是通过它来实现的,它的作用是把Applicationcontext 发布的 Event 广播给它的监听器列表。

2. 核心类

  • ApplicationEvent 事件类
  • ApplicationListener 监听器泛型(事件类)
  • @EventListener 注解同ApplicationListener 作用于方法上,参数是事件类
  • ApplicationEventPublisher 自动发布事件的处理类,常用的,他是一个借口,自定义时可重写它
  • ApplicationEventPublisherAware 接口类,用于业务处理中,它包含 setApplicationEventPublisher 的方法,用于指定ApplicationEventPublisher
  • ApplicationEventMulticaster 用于事件监听器的注册和事件的广播,编程不涉及,但是需要了解下

3. 说一下 原理,懂了基本就OVER了,涉及源码,不懂暂时可以

1. 广播器 (类结构)

  • ApplicationEventMulticaster接口:提供了添加/移除监听器以及广播事件给监听器的行为。

  • AbstractApplicationEventMulticaster抽象类:提供了基础的监听器注册/移除以及查找能力。

  • SimpleApplicationEventMulticaster类:提供了事件广播功能。

2. 注册广播器和监听器

Spring容器初始化时, org.springframework.context.support.AbstractApplicationContext 在refresh()方法中,会进行广播器和监听器的注册。

  • 初始化事件广播器(initApplicationEventMulticaster)
  • 注册监听器(registerListeners)
  • 事件广播
    • publistEvent
    • multicastEvent

4. 实操效果

  • 定义事件
@EqualsAndHashCode(callSuper = true)
@Data
@Builder
public class DemoEvent extends ApplicationEvent {

    private String name;

    public DemoEvent(String source) {
        super(source);
        this.name = source;
    }

    public DemoEvent(Object source, Clock clock) {
        super(source, clock);
    }
}
  • 定义事件监听
方式一:采用注解 适合业务编程

@Component
public class DemoEventListener {

    @EventListener(DemoEvent.class)
    public void demoListener(DemoEvent event){
        System.out.println(event.getName());
    }
}

方式二: 适合底层框架编程
public class DemoEventListenerIm implements ApplicationListener<DemoEvent> {

    @Override
    public void onApplicationEvent(DemoEvent event) {
        System.out.println(event.getName());
    }
}
  • 定义事件发布(可不写,框架编程需要)
@Component
public class DemoPublisher implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void publishEvent(DemoEvent event) {
        System.out.println("publish event");
        applicationEventPublisher.publishEvent(event);
    }

}
  • 测试
@SpringBootTest(classes = EventApplication.class)
@RunWith(SpringRunner.class)
public class TestApplication {
    
    @Autowired
    private ApplicationEventPublisher publisher;

    @Test
    public void demoEvenTest() {
        DemoEvent demoEvent = new DemoEvent("hello");
        publisher.publishEvent(demoEvent);
        System.out.println("laile");
    }
}

5. 其他注意点

  • 事务监听器

    @EnableTransactionManagement开启事务支持,@TransactionalEventListener标识事务监听器。

    • 发布事件的操作必须在事务(@Transactional)内进行,否则监听器不会生效,也可以将fallbackExecution标志设置为true(@TransactionalEventListener(fallbackExecution = true))
    • 可以配置在事务的哪个阶段来监听事务(默认在事务提交后监听),@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)。
  • 异步支持

    @EnableAsync开启异步支持,@Async标识监听器异步处理。开启异步执行后,方法的异常不会抛出,只能在方法内部处理。

  • 条件监听

    @EventListener(condition = “#event.message.contains(‘important’)”)
    用于按照条件处理数据,可用与区分数据处理

  • 监听器顺序

    @Order控制多个监听器的执行顺序,值越小,监听器越先执行。

到这里您基本就了解了事件编程思路。 下面我们聊一聊前端的事件编程。KOI技术-事件驱动编程(前端)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为消费级QLC SSD来了

近日&#xff0c;有关消息显示&#xff0c;华为的消费级SSD产品线&#xff0c;eKitStor Xtreme 200E系列&#xff0c;在韩国一家在线零售商处首次公开销售&#xff0c;引起了业界的广泛关注。 尽管华为已经涉足服务器级别的SSD制造多年&#xff0c;但直到今年6月才正式推出面向…

007-构建工具大进步:Amper Amper Amper!

Amper Amper Amper! 今天天气不好&#xff0c;送孩子上少年宫之后就在茶馆里坐着。突然看到一个帖子&#xff1a;Project configuration with Amper&#xff0c;看得心情大好。 用Kotlin也有个大概几年的时间&#xff0c;开发了几个小工具&#xff0c;感觉很是不错。但是配置…

STM32 高级 物联网通讯之LoRa通讯

目录 LoRa通讯基础知识 常见的3种通讯协议 远距离高速率的传输协议 近距离高速率传输技术 近距离低功耗传输技术 低功耗广域网 采用授权频段技术 非授权频段 LoRa简介 LoRa的特点 远距离 低功耗 安全 标准化 地理定位 移动性 高性能 低成本 LoRa应用 LoRa组…

SAP月结、年结前重点检查事项(后勤与财务模块)

文章目录 一、PP生产模块相关的事务检查二、SD销售模块相关的事务检查:三、MM物料管理模块相关的事务检查四、FICO财务模块相关的事务检查五、年结前若干注意事项【SAP系统PP模块研究】 #SAP #生产订单 #月结 #年结 一、PP生产模块相关的事务检查 1、月末盘点后,生产用料的…

重装操作系统后 Oracle 11g 数据库数据还原

场景描述&#xff1a; 由于SSD系统盘损坏&#xff0c;更换硬盘后重装了操作系统&#xff0c;Oracle数据库之前安装在D盘(另一个硬盘)&#xff0c;更换硬盘多添加一个盘符重装系统后盘符从D变成E&#xff0c;也就是之前的D:/app/... 变成了现在的 E:/app/...&#xff0c;重新安装…

2D图像测量到3D点云之物体三维尺寸测量!!!!

0&#xff0c;引言 本文将从双目采集的2D图像到3D点云进行转化&#xff0c;并进行物体尺寸测量&#xff0c;旨在为读者展示2D图像如何关联3D点云&#xff0c;并进行相关工业应用。 将2D图像转化为3D点云&#xff0c;并进行物体尺寸测量的技术&#xff0c;在工业领域有着广泛的…

python 渗透开发工具之SQLMapApi Server不同IP服务启动方式处理 解决方案SqlMapApiServer外网不能访问的情况

目录 说在前面 什么是 SQLMapAPI 说明 sqlmapApi能干什么 sqlmapApi 服务安装相关 kali-sqlmap存放位置 正常启动sqlmap-api server SqlMapApi-Server 解决外网不能访问情况 说在前面 什么是sqlmap 这个在前面已经说过了&#xff0c;如果这个不知道&#xff0c;就可以…

如何添加使用高德地图资源

‌高德地图瓦片地址包括以下几种类型‌&#xff1a;‌12 ‌矢量底图‌&#xff1a; 地址&#xff1a;https://wprd04.is.autonavi.com/appmaptile?langzh_cn&size1&scale1&style7&x{x}&y{y}&z{z}描述&#xff1a;包含路网和注记的矢量底图。 ‌卫星影…

智能家居体验大变革 博联 AI 方案让智能不再繁琐

1. 全球AI技术发展背景及智能家居市场趋势 人工智能&#xff08;AI&#xff09;技术的飞速发展正在推动全球各行业的数字化转型。国际电信联盟与德勤联合发布《人工智能向善影响》报告指出&#xff0c;全球94%的商界领袖认为&#xff0c;人工智能技术对于其企业在未来5年内的发…

第三代增强经典BADI-增强菜单栏和子屏幕

文章目录 创建经典BADI实施BADI创建屏幕绘制屏幕 定义GUI运行结果程序代码 创建经典BADI 实施BADI 创建屏幕 绘制屏幕 定义GUI 运行结果 程序代码 *&---------------------------------------------------------------------* *& Report ZRP_BADITEST *& *&-…

联通 路由器 创维SK-WR9551X 联通华盛VS010 组mesh 和 锐捷X32 PRO 无缝漫游

前言 联通路由器&#xff1a;联通创维SK-WR9551X&#xff0c;联通华盛VS010组mesh&#xff0c;并与锐捷X32 PRO混合组网&#xff0c;开启无限漫游。 1、mesh ≠ 无缝漫游 mesh是实现路由器快速组网的一种方式&#xff0c;通过mesh组网后可以实现无缝漫游。 mesh组网的设备要…

如何使用大语言模型进行事件抽取与关系抽取

诸神缄默不语-个人CSDN博文目录 文章目录 1. 什么是事件抽取与关系抽取&#xff1f;2. 示例&#xff1a;使用大语言模型进行事件抽取与关系抽取 1. 什么是事件抽取与关系抽取&#xff1f; 事件抽取是指从文本中识别出与某些“事件”相关的信息。这些事件通常包括动作、参与者、…

Mysql COUNT() 函数详解

简介 COUNT()函数定义 COUNT()函数是SQL中常用的 聚合函数 &#xff0c;用于统计满足特定条件的记录数。它可以灵活地应用于各种查询场景&#xff0c;帮助用户快速获取所需的数据统计信息。该函数不仅能够计算所有行的数量&#xff0c;还能针对特定列进行计数&#xff0c;并支…

SD卡恢复数据:快速找回丢失文件!

由于其小尺寸和便携性&#xff0c;SD卡作为外部存储设备在用户中广泛应用。它适用于各种设备&#xff0c;例如数码相机、摄像机、音乐播放器、手机、电视、无人机等。 但是&#xff0c;与其他类型的存储设备一样&#xff0c;SD卡很精致&#xff0c;使用一段时间后可能会出现程…

OpenStack系列第四篇:云平台基础功能与操作(Dashboard)

文章目录 1. 镜像&#xff08;Image&#xff09;添加镜像查看镜像删除镜像 2. 卷&#xff08;Volume&#xff09;创建卷查看卷删除卷 3. 网络&#xff08;虚拟网络&#xff09;创建网络查看网络删除网络 4. 实例类型创建实例类型查看实例类型删除实例类型 4. 密钥对&#xff08…

HTML——43.创建表格

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表格</title></head><body><!--table标签用来定义表格&#xff0c;border属性表示边框--><!--tr标签表示表格中的一行--><!--th标签表示表…

Sony偏振传感器加持 Blackfly S工业相机突破视觉成像反光难题【51camera】

为什么采用传感器偏振? A: 视觉系统一直都在试图克服玻璃、塑料和金属等反光表面产生的动态或多余光线、反射、朦胧和眩光影响。Teledyne FLIR的Blackfly S 机器视觉工业相机具有 Sony 的传感器偏振和 Spinnaker SDK 内置的防眩光功能&#xff0c;提供便于实施、轻量化且可靠…

Linux上安装配置单节点zookeeper

直接先去官网下载安装包&#xff0c; https://downloads.apache.org/zookeeper/ 选择合适的版本&#xff0c;然后上传至服务器 解压&#xff1a; tar -zxvf apache-zookeeper-3.9.3-bin.tar.gz创建data和logs目录 mkdir data mkdir logs配置环境变量&#xff1a; vim /etc/p…

零基础入门指针的应用

对于我这个非计算机专业的人来说&#xff0c;指针真的很让我头疼&#xff0c;该如何理解指针、如何使用指针是我的痛点&#xff0c;但是在嵌入式中又会经常用的到&#xff0c;所以本文将介绍该如何求使用指针。 一、指针的概念 什么是指针&#xff1f;指针就是编程语言中的一个…

Oracle Dataguard(主库为 Oracle 11g 单节点)配置详解(1):Oracle Dataguard 概述

Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Dataguard 概述 目录 Oracle Dataguard&#xff08;主库为 Oracle 11g 单节点&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;Oracle Data…