`

Guava学习笔记:EventBus

 
阅读更多
http://my.oschina.net/u/2311010/blog/515188
摘要 EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。   Observer模式是比较常用的设计模式之一,虽然有时候在具体代码里,它不一定叫这个名字,比如改头换面叫个Listener,但模式就是这个模式。手工实现一个Observer也不是多复杂的一件事,只是因为这个设计模式实在太常用了,Java就把它放到了JDK里面:Observable和Observer,从JDK 1.0里,它们就一直在那里。从某种程度上说,它简化了Obser...



EventBus基本用法:

使用Guava之后, 如果要订阅消息, 就不用再继承指定的接口, 只需要在指定的方法上加上@Subscribe注解即可。代码如下:

消息封装类:
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



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的方式来记录这种状态。

Event的继承:

如果Listener A监听Event A, 而Event A有一个子类Event B, 此时Listener A将同时接收Event A和B消息,实例如下:

Listener 类:
public class NumberListener {  
        
    private Number lastMessage;  
    
    @Subscribe  
    public void listen(Number integer) {  
        lastMessage = integer; 
        System.out.println("Message:"+lastMessage);
    }  
    
    public Number getLastMessage() {  
        return lastMessage;  
    }  
}  
 
public class IntegerListener {  
        
    private Integer lastMessage;  
    
    @Subscribe  
    public void listen(Integer integer) {  
        lastMessage = integer; 
        System.out.println("Message:"+lastMessage);
    }  
    
    public Integer getLastMessage() {  
        return lastMessage;  
    }  
}

测试类:
public class TestEventsFromSubclass {
    @Test  
    public void testEventsFromSubclass() throws Exception {  
        
        EventBus eventBus = new EventBus("test");  
        IntegerListener integerListener = new IntegerListener();  
        NumberListener numberListener = new NumberListener();  
        eventBus.register(integerListener);  
        eventBus.register(numberListener);  
        
        eventBus.post(new Integer(100));  
        
        System.out.println("integerListener message:"+integerListener.getLastMessage());
        System.out.println("numberListener message:"+numberListener.getLastMessage());
               
        eventBus.post(new Long(200L));  
        
        System.out.println("integerListener message:"+integerListener.getLastMessage());
        System.out.println("numberListener message:"+numberListener.getLastMessage());        
    }  
}


//输出类
Message:100
Message:100
integerListener message:100
numberListener message:100
Message:200
integerListener message:100
numberListener message:200


说明:在这个方法中,我们看到第一个事件(新的整数(100))是收到两个听众,但第二个(新长(200 l))只能到达NumberListener作为整数一不是创建这种类型的事件。可以使用此功能来创建更通用的监听器监听一个广泛的事件和更详细的具体的特殊的事件。

一个综合实例:
public class UserThread extends Thread {
    private Socket connection;
    private EventBus channel;
    private BufferedReader in;
    private PrintWriter out;
 
    public UserThread(Socket connection, EventBus channel) {
        this.connection = connection;
        this.channel = channel;
        try {
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            out = new PrintWriter(connection.getOutputStream(), true);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
 
    @Subscribe
    public void recieveMessage(String message) {
        if (out != null) {
            out.println(message);
            System.out.println("recieveMessage:"+message);
        }
    }
 
    @Override
    public void run() {
        try {
            String input;
            while ((input = in.readLine()) != null) {
                channel.post(input);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
         
        //reached eof
        channel.unregister(this);
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        in = null;
        out = null;
    }
} 

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
 
import com.google.common.eventbus.EventBus;
 
public class EventBusChat {
    public static void main(String[] args) {
        EventBus channel = new EventBus();
        ServerSocket socket;
        try {
            socket = new ServerSocket(4444);
            while (true) {
                Socket connection = socket.accept();
                UserThread newUser = new UserThread(connection, channel);
                channel.register(newUser);
                newUser.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

说明:用telnet命令登录:telnet 127.0.0.1 4444 ,如果你连接多个实例你会看到任何消息发送被传送到其他实例。
分享到:
评论

相关推荐

    guava-11.0.2-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:11.0.2; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

    guava-18.0-API文档-中英对照版.zip

    赠送jar包:guava-18.0.jar 赠送原API文档:guava-18.0-javadoc.jar 赠送源代码:guava-18.0-sources.jar 包含翻译后的API文档:guava-18.0-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven信息:groupId...

    guava-23.0-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:23.0; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...

    guava-24.1-jre-API文档-中英对照版.zip

    Maven坐标:com.google.guava:guava:24.1-jre; 标签:google、guava、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...

    Guava常用类库 v33.0.0.zip

    9. **事件监听**:EventBus是Guava的一个轻量级发布/订阅事件系统,使得不同组件之间的通信变得简单。 10. **枚举Set**:Guava的EnumSet是专门为枚举类型设计的高效集合,它的性能优于Java内置的HashSet。 在Guava...

    guava-26.0-android-API文档-中文版.zip

    Maven坐标:com.google.guava:guava:26.0-android; 标签:google、guava、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...

    guava-30.1-jre.jar

    Guava是Google开发的一个开源Java库,包含了众多的实用工具类和集合框架,极大地提高了Java开发的效率。在本例中,我们关注的是"guava-30.1-jre.jar",这是一个针对Java运行环境(JRE)优化的Guava版本,版本号为...

    guava-25.1-jre.jar

    google的guava工具包很实用,包括之前的字符串处理工具类的,还有大量的collection相关的

    guava-18.0(guava-18.0.jar和guava-18.0-sources.jar)

    8. **事件监听**:Guava的EventBus可以方便地实现发布/订阅模式,简化事件驱动的编程。 9. **枚举集与常量**:Guava提供了ImmutableEnumSet和ImmutableSet.of()等方法,创建不可变且高效的枚举集合。 `guava-18.0-...

    fact-bus:基于guava整合spring实现EventBus;具体详情请访问:https

    SNAPSHOTMaven依赖<dependency><groupId>com.woter.fact</groupId><artifactId>fact-bus</artifactId><version>1.0.0-SNAPSHOT</version></dependency>功能描述fact-bus 是基于guava整合spring实现EventBus;...

    最新版 guava-30.1-jre.jar

    最新版 guava-30.1-jre.jar

    guava-31.1-jre.jar

    guava

    Guava-Event-Bus:Guava的EventBus源码学习

    Guava-Event-Bus 学习笔记 Guava的EventBus源码学习,基于Guava的18.0版本 分析者: ###1. 背景简介 EventBus是google的一个Java工具包其中的一个工具类,类似的有多个版本其中包括移植到Android端的 和改良的,功能...

    guava-19.0 jar和sources

    开发者可以通过查看这些源代码来理解Guava内部的工作原理,方便进行学习、调试和扩展。源码文件对于开发者来说是非常有价值的,特别是当遇到使用问题或想要自定义Guava功能时。 标签中的"guava"是指Guava库本身,它...

    guava-18.0-API文档-中文版.zip

    赠送jar包:guava-18.0.jar; 赠送原API文档:guava-18.0-javadoc.jar; 赠送源代码:guava-18.0-sources.jar; 包含翻译后的API文档:guava-18.0-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:...

    guava-r09-jarjar.jar

    标题中的"guava-r09-jarjar.jar"是一个特定版本的Guava库,经过JarJar工具处理后的结果。Guava是Google的一个核心库,它提供了很多Java平台的基础工具,包括集合、缓存、原生类型支持、并发、函数式编程、字符串处理...

    Google的Guava工具包

    Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你...

    google开源项目guava.jar包

    谷歌的Guava库是Java开发中的一个非常重要的开源项目,它提供了一系列的高效、实用的工具类,大大简化了常见的编程任务。Guava的核心特性包括集合框架、缓存、原生类型支持、并发库、字符串处理、I/O操作等。这个...

    guava-32.1.3-android.jar

    javaweb/javaee 常用jar包,亲测可用,若需其他版本其他jar包请留言我看到后会上传分享

    guava-12.0.1-API文档-中英对照版.zip

    赠送jar包:guava-12.0.1.jar; 赠送原API文档:guava-12.0.1-javadoc.jar; 赠送源代码:guava-12.0.1-sources.jar; 包含翻译后的API文档:guava-12.0.1-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven...

Global site tag (gtag.js) - Google Analytics