专注IT技术、资源分享!
Guava事件总线EventBus
Guava事件总线EventBus

Guava事件总线EventBus

Guava是一个谷歌开发的开源库。Guava工程中包含了很多被Google的 Java项目广泛依赖的核心库。

本文主要介绍Guava中的EventBus组件。

EventBus

Eventbus是一种机制,它允许不同的组件在不了解彼此的情况下相互通信。组件可以将Event发送到Eventbus,而不知道谁将接收它,或者有多少其他组件将接收它。组件还可以监听Eventbus上的事件,而不知道是谁发送了事件。这样,组件就可以在不依赖彼此的情况下进行通信。另外,替换一个组件也很容易。只要新组件理解正在发送和接收的Events,其他组件就永远不会知道。

引入依赖

  <dependency>
     <groupId>com.google.guava</groupId>
     <artifactId>guava</artifactId>
     <version>18.0</version>
 </dependency>

快速使用

创建EventBus

使用Eventbus时,首先,为了注册监听器和发布事件,你需要一个总线:

EventBus eventBus=new EventBus();

创建监听器

然后需要创建一个监听器,用于订阅EventBus上的事件。

public class MyEventListener{
private static int numberEvents;
private static List<String> eventsList=new ArrayList<>();
@Subscribe
public void myEvent(String event) {
System.out.println(event);
numberEvents++;
}

注册监听器并发布事件

可以看到,处理程序方法使用@Subscribe注解;现在Listener应该被添加到Eventbus和发布事件。下面是一个简单的例子:

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class EventBusTest {

  class EventListener{
     private  int numberEvents;
     @Subscribe
     public void myEvent(String event) {
         System.out.println(event);
         numberEvents++;
    }
     public  int getNumberEvents(){
         return  numberEvents;
    }
}

@Test
public void testEventBusSimpleTest(){
EventBus eventBus=new EventBus();
EventListener listener = new EventListener();
eventBus.register(listener);
eventBus.post("event1");
eventBus.post("event2");
assertEquals(2, listener.getNumberEvents());
}
}

实际案例

是不是很简单!我们可以通过EventBus解决一些实际场景中的问题,在单个JVM中进行异步处理。比如在一些交易系统中,在付款成功以后,需要将结果通知给付款方,同时也要通知收款方。

在这个例子中,我们需要两个监听器,一个用于发送付款成功的消息给用户,一个用于发送消息给收款方。

首先有一个用于表示交易的类。

class Transaction {
   private final String transactionName;
   private double amount = 0.0;
   public Transaction(String transactionName, Double amount) {
       this.transactionName = transactionName;
       this.amount = amount;
  }
   public String getTransactionName() {
       return transactionName;
  }
   public double getAmount() {
       return amount;
  }
   @Override
   public String toString() {
       return "[transaction with name " + transactionName + " and amount " + amount + "]";
  }
}

然后建立两个监听器,用于监听交易完成的事件,并作出响应。

class SendPaymentListener {
   @Subscribe
   private void sendToPayment(Transaction transaction) {
       System.out.println("【付款方】交易" + transaction.getTransactionName() + "交易完成,金额:" + transaction.getAmount());
       // to do something...
  }
}

class SendReceiveListener {
   @Subscribe
   private void sendToPayment(Transaction transaction) {
       System.out.println("【收款方】交易" + transaction.getTransactionName() + "交易完成,金额:" + transaction.getAmount());
       // to do something...
  }
}

有了事件的订阅方之后,我们建立EventBus,并将监听器注册在EventBus上,然后将Event发布。

public class PaymentService {

   static class EventBusFactory {
       //create an asynch bus in new Thread
       private static EventBus eventBus
           = new AsyncEventBus(Executors.newCachedThreadPool());
       public static EventBus getEventBus() {
           return eventBus;
      }
  }
   
   @Test
   public void testPayment() {
       //registering listeners
       EventBusFactory.getEventBus().register(new SendPaymentListener());
       EventBusFactory.getEventBus().register(new SendReceiveListener());
       EventBusFactory.getEventBus().post(new Transaction("交易001", 100.0));
  }
}

我们执行测试用例后,结果如下:

可以看出,我们并不用显式的去调用SendPaymentListenerSendReceiveListener的方法,EventBus内部便可以替我们完成事件的发布。

小结

Guava EventBus的内容比较简单,所以上面内容也写的很简单,你可以动手试试,体验一下Guava的发布订阅模式。如果对你有所帮助,点个赞就是对我最大的鼓励!

发表回复

您的电子邮箱地址不会被公开。