This is the second day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

Guava is an open source library developed by Google. The Guava project includes many of the core libraries that Google’s Java project relies on extensively. This article focuses on the EventBus component in Guava.

EventBus

Eventbus is a mechanism that allows different components to communicate with each other without knowing about each other. A component can send an Event to Eventbus without knowing who will receive it or how many other components will receive it. Components can also listen for events on Eventbus without knowing who sent the event. In this way, components can communicate without depending on each other. Also, it’s easy to replace a component. As long as the new component understands the Events being sent and received, the other components will never know.

Introduction of depend on

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

Quick to use

Create the EventBus

When using Eventbus, first, to register listeners and publish events, you need a bus:

EventBus eventBus=new EventBus();
Copy the code

Create listeners

You then need to create a listener to subscribe to events on 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++;
 }
Copy the code

Register listeners and publish events

As you can see, the handler method uses the @subscribe annotation; Now the Listener should be added to the Eventbus and publish the event. Here’s a simple example:

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(a){
          returnnumberEvents; }}@Test
	public void testEventBusSimpleTest(a){
		EventBus eventBus=new EventBus();
		EventListener listener = new EventListener();
		eventBus.register(listener);
		eventBus.post("event1");
		eventBus.post("event2");
		assertEquals(2, listener.getNumberEvents()); }}Copy the code

The actual case

Isn’t it easy? EventBus can be used to solve some real-world problems, with asynchronous processing in a single JVM. For example, in some transaction systems, after the payment has been made, the result needs to be notified to the payer as well as to the receiver.

In this example, we need two listeners, one to send a successful payment message to the user and one to send a message to the payee.

First, there is a class that represents transactions.

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(a) {
        return transactionName;
    }
    public double getAmount(a) {
        return amount;
    }
    @Override
    public String toString(a) {
        return "[transaction with name " + transactionName + " and amount " + amount + "]"; }}Copy the code

Two listeners are then set up to listen for the transaction completion event and respond.

class SendPaymentListener {
    @Subscribe
    private void sendToPayment(Transaction transaction) {
        System.out.println("[Payer] Transaction" + transaction.getTransactionName() + "Transaction completed, amount :" + transaction.getAmount());
        // to do something...}}class SendReceiveListener {
    @Subscribe
    private void sendToPayment(Transaction transaction) {
        System.out.println([Payee] Transaction + transaction.getTransactionName() + "Transaction completed, amount :" + transaction.getAmount());
        // to do something...}}Copy the code

Once we have subscribers to events, we set up EventBus, register listeners with EventBus, and then publish events.

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(a) {
            returneventBus; }}@Test
    public void testPayment(a) {
        //registering listeners
        EventBusFactory.getEventBus().register(new SendPaymentListener());
        EventBusFactory.getEventBus().register(new SendReceiveListener());
        EventBusFactory.getEventBus().post(new Transaction("Trading 001".100.0)); }}Copy the code

After we execute the test case, the results are as follows:

As you can see, instead of explicitly calling the SendPaymentListener and SendReceiveListener methods, EventBus publishes events internally for us.

summary

Guava EventBus is relatively simple, so the above content is also very simple, so you can give it a try and experience with Guava’s publish and subscribe model. If it is helpful to you, a “like” is the biggest encouragement to me!