Google guava in the event message queue process bus EventBus

Here Insert Picture Description

Google guava and Apache commons similar to java language and class libraries are enhanced an extension library.
the birth of guava is that many efficient method of java Google engineers have extracted from their daily work collection.

Google guava library in the event there is a bus assembly (EventBus), which provides news release - subscription library implements the observer design pattern can easily be convenient business code decoupled.

For example, we can quickly establish a program message queue within a process by EventBus.

Because EventBus is to maintain a queue of messages in memory, so I do not support cross-process use.

Of course, if all you need is a cross-process, it should be distributed directly from the message queue middleware (RabbitMQ, kafka, etc.)

EventBus divided into synchronous and asynchronous (AsyncEventBus).

When an event is sent without any a EventBus a listener can handle the current event bus, then this event will be repackaged into DeadEvent resent.

Create an event bus Process

The concept event bus involved are:

Event news producer
event message
event listener (can be understood as an event message consumers)
event handler

Create a new event processing flow for the bus:

  1. Select or create a category event news
  2. Create an event listener class
  3. If you want to use asynchronous event bus need to create an Executor objects at this point (such as thread pool)
  4. Create a new event processing bus (EventBus, AsyncEventBus)
  5. Register event listeners (may be more)
  6. Send event messages
  7. Unbundling event listeners

Code Code

The introduction of dependence

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>28.2-jre</version>
        </dependency>

A simple event processing

Listener

/**
 * 事件监听类
 */
@Slf4j
class OrderEventListener{

    /**
     * @Subscribe 监听事件的处理方法;监听的事件对象类型可以是继承自Object的任何类。
     * @AllowConcurrentEvents 是在ASyncEventBus(异步事件总线中必要的),如果是EventBus则不用加上此注解
     * @param msg
     */
    @AllowConcurrentEvents
    @Subscribe
    public void eventFunc(JSONObject msg) {
        log.debug("*************" + this.getClass().getCanonicalName()+"************************");
        log.info("on message {} ", msg.toJSONString());
    }
}

Create an event bus producer, to register event listeners who send events

    @GetMapping("startEvent")
    public void testProc2(){
        log.info( "test starting ... ");
//        Creates a new EventBus with the given identifier.
        EventBus eventBus = new EventBus("orderEventBus");
//        Registers all subscriber methods on object to receive events.
        eventBus.register(new OrderEventListener());
//      新建一个事件消息对象
        JSONObject msg = new JSONObject();
        msg.put("orderNo", "orderNo000001");
        msg.put("userNo", "ochsaofhdhfodhfos00");
//      咱们来使用一个线程去发送事件消息
        Thread t1 = new Thread(()->{
            int i = 0;
            while (i < 100) {
                i++;
                try {
                    Thread.sleep(1000);
//                    发送事件消息
                    eventBus.post(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
    }

operation result

Here Insert Picture Description

Spread

At the same time register multiple event listeners who use interface class spring-hosted listener to do, DeadEvent use.

Multiple event listeners plus DeadEvent processing

Interface classes

/**
 * 事件处理接口
 */
public interface IEventListener{
    public void eventFunc(JSONObject msg);
}
/**
 * 事件监听类 扩展的
 */
@Component
@Slf4j
public class OrderEventListenerExt implements IEventListener {

    /**
     * @Subscribe 监听事件的处理方法;监听的事件对象类型可以是继承自Object的任何类。
     * @AllowConcurrentEvents 是在ASyncEventBus(异步事件总线中必要的),如果是EventBus则不用加上此注解
     * @param msg
     */

    @Override
    @AllowConcurrentEvents
    @Subscribe
    public void eventFunc(JSONObject msg) {
        log.debug("*************************************");
        log.info("on message {} ", msg.toJSONString());
    }
}

DeadEvent monitor

/**
 * DeadEvent事件监听类(可选的)
 * 当一个EventBus发送的一个事件在当前事件总线中没有任何一个监听者可以处理,那么这个事件会被重新包装成DeadEvent重新发送。
 */
@Slf4j
class DeadEventListener{

    /**
     * @Subscribe 监听事件的处理方法;监听的事件对象类型可以是继承自Object的任何类。
     * @AllowConcurrentEvents 是在ASyncEventBus(异步事件总线中必要的),如果是EventBus则不用加上此注解
     * @param msg
     */
    @AllowConcurrentEvents
    @Subscribe
    public void eventFunc(DeadEvent msg) {
        log.debug("*************" + this.getClass().getCanonicalName()+"************************");
        log.info("on message {} ", msg.toString());
    }
}

    @Autowired
    private IEventListener eventListener;

    @GetMapping("startEvent2")
    public void testProc4(){
        log.info( "test starting ...  ");
//        Creates a new EventBus with the given identifier.
        EventBus eventBus = new EventBus("orderEventBus");
//        Registers all subscriber methods on object to receive events.
        eventBus.register(eventListener);
        eventBus.register(new OrderEventListener());
        eventBus.register(new DeadEventListener());
//      新建一个事件消息对象
        JSONObject msg = new JSONObject();
        msg.put("orderNo", "orderNo000001");
        msg.put("userNo", "ochsaofhdhfodhfos00");
//      咱们来使用一个线程去发送事件消息
        Thread t1 = new Thread(()->{
            int i = 0;
            while (i < 100) {
                i++;
                try {
                    Thread.sleep(1000);
//                    发送事件消息
                    eventBus.post(msg);
                    eventBus.post(new String("deadeventmessage"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
    }


operation result

Here Insert Picture Description

The results can be seen:
Event bus registered in the n-type listening to JSON objects, when you send a JSON event of this event will be processed n times.
If the producer sends a registered listener can not handle events that this event will be sent packing back to DeadEvent.

Asynchronous Event Bus

    @GetMapping("startEventAsync")
    public void testProc3(){
        log.info( "test starting async event ... ");

        /**
         * 使用google guava async eventbus 我们需要一个线程池对象来管理事件处理线程
         * 我们可以选择jdk或者spring的线程池类
         */

//        JDK提供的线程池类
        ThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(1);
        threadPoolExecutor.setMaximumPoolSize(1);
        threadPoolExecutor.setKeepAliveTime(1, TimeUnit.SECONDS);
        threadPoolExecutor.allowCoreThreadTimeOut(false);
/**
 *      spring 提供的线程池类
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(1);
        threadPoolTaskExecutor.setMaxPoolSize(1);
        threadPoolTaskExecutor.setQueueCapacity(100);
        threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);
        threadPoolTaskExecutor.setKeepAliveSeconds(1000);
        threadPoolTaskExecutor.initialize();*/

//        AsyncEventBus eventBus = new AsyncEventBus("orderEventBusAsync", threadPoolTaskExecutor);
        AsyncEventBus eventBus = new AsyncEventBus("orderEventBusAsync", threadPoolExecutor);

//      不多说,依然是注册事件
//        不要忘记异步事件总线监听方法要加 @AllowConcurrentEvents
        eventBus.register(new OrderEventListener());

//      咱们来使用一个线程去发送事件消息
        Thread t1 = new Thread(()->{
            int i = 0;
            while (i < 100) {
                i++;
                try {
                    Thread.sleep(2000);
                    //      新建事件消息
                    JSONObject msg = new JSONObject();
                    msg.put("orderNo", "orderNo000001Async"+i);
                    msg.put("userNo", "ochsaofhdhfodhfos00");
                    eventBus.post(msg);
                    log.info("post message");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });

        t1.start();
    }

}

operation result

Here Insert Picture Description

Published 58 original articles · won praise 11 · views 20000 +

Guess you like

Origin blog.csdn.net/wangxudongx/article/details/104869047