guava学习--事件驱动模型

反光的小鱼儿 反光的小鱼儿     2022-08-20     311

关键词:

转载:http://www.cnblogs.com/whitewolf/p/4132840.html 

     http://www.cnblogs.com/peida/p/EventBus.html

 

更好的文章:https://my.oschina.net/realfighter/blog/406342

 

Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计。

不再多的废话,直奔Guava EventBus主题。首先Guava为我们提供了同步事件EventBus和异步实现AsyncEventBus两个事件总线,他们都不是单例的,官方理由是并不想我们我们的使用方式。当然如果我们想其为单例,我们可以很容易封装它,一个单例模式保证只创建一个实例就对了。

下面将以EventBus为例,AsyncEventBus使用方式与其一致的。

1.同步事件EventBus

 

订阅

首先EventBus为我们提供了register方法来订阅事件,Guava在这里的实现很友好,我们不需要实现任何的额外接口或者base类,只需要在订阅方法上标注上@Subscribe和保证只有一个输入参数的方法就可以搞定。

发布

对于事件源,则可以通过post方法发布事件。 正在这里对于Guava对于事件的发布,是依据上例中订阅方法的方法参数类型决定的,换而言之就是post传入的类型和其基类类型可以收到此事件。

建议对于每类事件封装一个特定的事件类型是必要的。

 

消息封装类:

public class TestEvent {
    private final int message;
    public TestEvent(int message) {        
        this.message = message;
        System.out.println("event message:"+message);
    }
    public int getMessage() {
        return message;
    }
}

消息接收类:

public class EventListener {
    public int lastMessage = 0;

    @Subscribe
    public void listen(TestEvent event) {
        lastMessage = event.getMessage();
        System.out.println("Message:"+lastMessage);
    }

    public int getLastMessage() {      
        return lastMessage;
    }
}

测试类及输出结果:

public class TestEventBus {
    @Test
    public void testReceiveEvent() throws Exception {

        EventBus eventBus = new EventBus("test");
        EventListener listener = new EventListener();

        eventBus.register(listener);

        eventBus.post(new TestEvent(200));
        eventBus.post(new TestEvent(300));
        eventBus.post(new TestEvent(400));

        System.out.println("LastMessage:"+listener.getLastMessage());
        ;
    }
}

//输出信息
event message:200
Message:200
event message:300
Message:300
event message:400
Message:400
LastMessage:400

MultiListener的使用:

  只需要在要订阅消息的方法上加上@Subscribe注解即可实现对多个消息的订阅,代码如下:

public class MultipleListener {
    public Integer lastInteger;  
    public Long lastLong;  
   
    @Subscribe  
    public void listenInteger(Integer event) {  
        lastInteger = event; 
        System.out.println("event Integer:"+lastInteger);
    }  
   
    @Subscribe  
    public void listenLong(Long event) {  
        lastLong = event; 
        System.out.println("event Long:"+lastLong);
    }  
   
    public Integer getLastInteger() {  
        return lastInteger;  
    }  
   
    public Long getLastLong() {  
        return lastLong;  
    }  
}

  测试类:

public class TestMultipleEvents {
    @Test  
    public void testMultipleEvents() throws Exception {  
       
        EventBus eventBus = new EventBus("test");  
        MultipleListener multiListener = new MultipleListener();  
       
        eventBus.register(multiListener);  
       
        eventBus.post(new Integer(100));
        eventBus.post(new Integer(200));  
        eventBus.post(new Integer(300));  
        eventBus.post(new Long(800)); 
        eventBus.post(new Long(800990));  
        eventBus.post(new Long(800882934));  
       
        System.out.println("LastInteger:"+multiListener.getLastInteger());
        System.out.println("LastLong:"+multiListener.getLastLong());
    }   
}

//输出信息
event Integer:100
event Integer:200
event Integer:300
event Long:800
event Long:800990
event Long:800882934
LastInteger:300
LastLong:800882934

在这里有 Integer,Long,与它们基类Number。我们发送一个整数数据的时候,或者Integer和Number的方法接收,而Long类型则Long类型和Number类型接受。
可以使用此功能来创建更通用的监听器监听一个广泛的事件和更详细的具体的特殊的事件。(是类似的意思,看懂即可)。

Dead Event:

  如果EventBus发送的消息都不是订阅者关心的称之为Dead Event。实例如下:

public class DeadEventListener {
    boolean notDelivered = false;  
       
    @Subscribe  
    public void listen(DeadEvent event) {  
        
        notDelivered = true;  
    }  
   
    public boolean isNotDelivered() {  
        return notDelivered;  
    }  
}

  测试类:

public class TestDeadEventListeners {
    @Test  
    public void testDeadEventListeners() throws Exception {  
       
        EventBus eventBus = new EventBus("test");               
        DeadEventListener deadEventListener = new DeadEventListener();  
        eventBus.register(deadEventListener);  

        eventBus.post(new TestEvent(200));         
        eventBus.post(new TestEvent(300));        
       
        System.out.println("deadEvent:"+deadEventListener.isNotDelivered());

    }  
}

//输出信息
event message:200
event message:300
deadEvent:true

说明:如果没有消息订阅者监听消息, EventBus将发送DeadEvent消息,这时我们可以通过log的方式来记录这种状态。

更好的文章:https://my.oschina.net/realfighter/blog/406342

guava源码学习eventbus

基于版本:Guava22.0Wiki:EventBus 0.EventBus简介提供了发布-订阅模型,可以方便的在EventBus上注册订阅者,发布者可以简单的将事件传递给EventBus,EventBus会自动将事件传递给相关联的订阅者。支持同步/异步模式。只能用于线程间... 查看详情

guava之eventbus事件驱动。

...对观察者模式的一种实现,使用EventBus可以很简洁的实现事件注册监听和消费。 packagecom.boot.demo.test.eventbus;importcom.google.common.eventbus.EventBus;importcom.google.common.eventbus.Subscribe;/***@authorbraska*@date2020/3/26**/publicclassEventBusTest//定义监... 查看详情

跟我学android之四事件驱动模型

Android事件驱动模型需要深刻学习和理解,事件驱动模型三要素如下:事件驱动模型事件源:事件的制造者,如:按钮通常会拥有注册和取消监听器的功能监听器:事件的接收者,通常是自己编写的类的对象一个实现了事件源所... 查看详情

libevent学习过程

...是工作时维护人家的代码碰到的,得深入了解,记录一下学习过程。  首先的问题是libevent是什么?查了一下,有个基本认识。Libevent是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动(e... 查看详情

salesforcelightning零基础学习事件(componentevents)简单介绍(代码片段)

lightningcomponent基于事件驱动模型来处理用户界面的交互。这种事件驱动模型和js的事件驱动模型也很相似,可以简单的理解成四部分:1.事件源:产生事件的地方,可以是页面中的输入框,按钮等等;2.事件:点击,失去焦点,初... 查看详情

关于协程的学习&线程栈默认10m

先看的这篇文章:http://blog.csdn.net/qq910894904/article/details/41699541以nginx为代表的事件驱动的异步server正在横扫天下,那么事件驱动模型会是server端模型的终点吗?我们可以深入了解下,事件驱动编程的模型。事件驱动编程的架构是... 查看详情

node-学习笔记

什么是Node.js1)Node.js是一个基于ChromeV8引擎的JavaScript运行环境2)Node.js使用了一个事件驱动、非阻塞式I/O的模型,使其轻量又高效。   ①事件驱动:当触发某个事件的时候,执行事件中指定的代码。   ②非... 查看详情

事件驱动模型

传统的编程与事件驱动模型传统的编程是:程序开始→代码块A→代码块B→代码块C→...→程序结束事件驱动模型是:(提高效率的表现)程序开始→初始化→等待事件驱动模型:事件驱动模型,在程序开始(启动)之后,就开始... 查看详情

事件驱动模型初探

事件驱动描述:鼠标的一个点击,移动,键盘的按键按下等等操作,都是对应操作系统的一个事件,然后应用程序接受你的操作进行处理核心概念:从程序设计的角度来看,事件驱动模型的核心构件通常包含(事件源:负责产生... 查看详情

nginx事件驱动模型(秒懂+史上最全)(代码片段)

...01;Java高并发发烧友社群:疯狂创客圈奉上以下珍贵的学习资源:免费赠送经典图书:《Java高并发核心编程(卷1)》面试必备+大厂必备+涨薪必备加尼恩免费领免费赠送经典图书:《Java高并发核心编程(卷2... 查看详情

yarn的asyncdispatcher学习(代码片段)

...件的派发. YARN中AsyncDispatcher的基本架构图如下:然后再学习一下AsyncDispatcher的类图:  所有的event 从基本的架构图可以简单的看出,该模型还需要几个基本的要素,那就是事件(Even 查看详情

使用事件驱动模型实现高效稳定的网络服务器程序

...用非阻塞接口的服务器模型、利用select()接口实现的基于事件驱动的服务器模型,和使用libev事件驱动库的服务器模型。通过比较各个模型,得出事件驱动模型更适合构建高效稳定的网络服务器程序的结论。前言 查看详情

对node.js事件驱动模型的深入理解

本文主要讨论以下问题:1.Node.js的事件驱动模型分析2.Node.js如何处理高并发请求?3.Node.js的缺点介绍先简单介绍一下Node.js,Node.js是基于事件驱动、非阻塞I/O模型的服务器端JavaScript运行环境,是基于Google的V8引擎在服务器端运行的... 查看详情

事件驱动模型

一、为什么要用事件驱动模型?在UI编程中,常常要对鼠标点击进行相应,首先如何获得鼠标点击呢?方式一:创建一个线程,该线程一直循环检测是否有鼠标点击。那么这个方式有以下几个缺点:1.CPU资源浪费,可能鼠标点击... 查看详情

事件驱动模型

...处理该请求;  (3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求上面的几种方式,各有千秋,第(1)中方法,由于创建新的进程的开销比较大,所以,会 查看详情

事件驱动模型和反应器模式有啥区别? [关闭]

】事件驱动模型和反应器模式有啥区别?[关闭]【英文标题】:Whatisthedifferencebetweeneventdrivenmodelandreactorpattern?[closed]事件驱动模型和反应器模式有什么区别?[关闭]【发布时间】:2012-02-2615:21:47【问题描述】:来自***ReactorPattern文... 查看详情

事件驱动模型

从setTimeout说起这是一个JS引擎当中内置的定时器函数官方的定义如下setTimeout()方法用于在指定的毫秒数后调用函数或计算表达式但是实践证明,即使是setTimeout(fn,0)fn函数也不会立即被执行例如下列代码console.log(1);vartimeFunc=function(){... 查看详情

事件驱动模型介绍(代码片段)

...线程,来处理该请求;(3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求第三种就是协程、事件驱动的方式,一般普遍认为第(3)种方式是大多数网络服务器采用的方式。 在UI编程中,常常... 查看详情