首页 > Java > java教程 > 正文

Java-类库-Guava-EventBus

黄舟
发布: 2017-01-19 13:12:55
原创
1726人浏览过

  eventbus是guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,eventbus是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。

  observer模式是比较常用的设计模式之一,虽然有时候在具体代码里,它不一定叫这个名字,比如改头换面叫个listener,但模式就是这个模式。手工实现一个observer也不是多复杂的一件事,只是因为这个设计模式实在太常用了,java就把它放到了jdk里面:observable和observer,从jdk 1.0里,它们就一直在那里。从某种程度上说,它简化了observer模式的开发,至少我们不用再手工维护自己的observer列表了。不过,如前所述,jdk里的observer从1.0就在那里了,直到java 7,它都没有什么改变,就连通知的参数还是object类型。要知道,java 5就已经泛型了。java 5是一次大规模的语法调整,许多程序库从那开始重新设计了api,使其更简洁易用。当然,那些不做应对的程序库,多半也就过时了。这也就是这里要讨论知识更新的原因所在。今天,对于普通的应用,如果要使用observer模式该如何做呢?答案是guava的eventbus。 

  eventbus基本用法:

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

  消息封装类: 

[code]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;
    }
}
登录后复制

 消息接受类: 

[code]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;
    }
}
登录后复制

测试类及输出结果:

[code]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注解即可实现对多个消息的订阅,代码如下: 

[code]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;  
    }  
}
登录后复制
[code]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。实例如下 

立即学习Java免费学习笔记(深入)”;

库宝AI
库宝AI

库宝AI是一款功能多样的智能伙伴助手,涵盖AI写作辅助、智能设计、图像生成、智能对话等多个方面。

库宝AI 109
查看详情 库宝AI
[code]public class DeadEventListener {
    boolean notDelivered = false;  

    @Subscribe  
    public void listen(DeadEvent event) {  

        notDelivered = true;  
    }  

    public boolean isNotDelivered() {  
        return notDelivered;  
    }  
}
登录后复制
[code]public class DeadEventListener {
    boolean notDelivered = false;  

    @Subscribe  
    public void listen(DeadEvent event) {  

        notDelivered = true;  
    }  

    public boolean isNotDelivered() {  
        return notDelivered;  
    }  
}
登录后复制

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

  Event的继承:

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

  Listener 类:

[code]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;  
    }  
}
登录后复制
[code]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作为整数一不是创建这种类型的事件。可以使用此功能来创建更通用的监听器监听一个广泛的事件和更详细的具体的特殊的事件。

  一个综合实例:

[code]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;
    }
}
登录后复制
[code]mport 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 ,如果你连接多个实例你会看到任何消息发送被传送到其他实例

以上就是Java-类库-Guava-EventBus的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关标签:
java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号