EventBus, AsyncEventBus explicación detallada y casos de uso

EventBus, como su nombre indica, es un modelo ligero de aplicación de publicación / suscripción. Comparado con MQ, es más conciso y liviano, y se puede usar dentro de un módulo de sistema pequeño. Si también estás interesado en EventBus, o quieres saber qué es EventBus, ven conmigo. Más tarde, te enseñaré cómo usar EventBus. A continuación, déjame entrar en EventBus.

1. Introducción y escenarios de uso de EventBus

EventBus es un bus de eventos en la biblioteca Guava de Google que maneja la comunicación entre componentes. Se basa en el modelo de publicación / suscripción y realiza el desacoplamiento de la comunicación entre varios componentes. Los productores de eventos y los consumidores de eventos están desacoplados y separados, lo que mejora la comunicación. La simplicidad .

¿Por qué utilizar Event Bus?

Cuando ocurre un evento (productor de eventos) y es necesario activar muchos eventos (consumidor de eventos), generalmente llamamos a esos consumidores de eventos por separado en el productor de eventos, lo que a menudo es una pérdida de recursos. El productor del evento y el consumidor del evento están sumamente emparejados. Si queremos cambiar un consumidor de eventos, es probable que cambiemos el productor del evento.

Escenario de uso: en el trabajo, a menudo nos encontramos con el uso de métodos asincrónicos para enviar eventos o desencadenar otra acción: el marco que se usa a menudo es MQ (notificación distribuida). Si se notifica en el mismo jvm, se puede utilizar EventBus. Debido a que EventBus es simple y conveniente de usar, a menudo se usa en el trabajo.

 

Dos, los tres puntos clave de EventBus

EventBus tiene tres elementos clave:

 

 

1. Evento

El evento es la unidad básica de comunicación mutua entre EventBus, un evento puede ser de cualquier tipo. Sí, sí, es Object. Siempre que quieras usar cualquier Bean como evento, esta clase puede usarse como evento sin ningún cambio. Sin embargo, en el proyecto, no será tan casual (a menos que no exista un requisito de rigor del código ...), generalmente se define una clase de evento específica, el nombre de la clase tiene el sufijo Event y algunas variables o funciones se definen dentro .

 

2. Editor de eventos (editor)

El editor del evento es la parte que envía el evento al bus de eventos EventBus. El editor del evento llama al método Post () para enviar el evento a EventBus. Puede llamar al método post () de EventBus en cualquier parte del programa para enviar eventos a EventBus y EventBus para enviar a los suscriptores.

 

3. Suscriptores de eventos (suscriptor)

Los suscriptores del evento son la parte que recibe el evento. Estos suscriptores deben agregar anotaciones @Subscribe a sus métodos para declararse como suscriptores del evento. Sin embargo, simplemente declarar no es suficiente, también necesitas registrar tu clase en EventBus para que EventBus pueda escanear este suscriptor.

 

 

Tres, implementar manualmente los casos EventBus y AsyncEventBus

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

 

A continuación, observe la estructura de directorios de este caso:

 

Introducción a la estructura del directorio:

evento: una clase de evento personalizada, el contenido de la clase se define libremente.

eventListeners: Se definen dos clases de escucha de eventos.Los métodos de la clase se anotan con @Subscribe.

util: clase de herramienta eventBus.

TestMain clase, función de prueba.

En este caso, las variables EventBus y AsyncEventBus se declaran en la clase de herramienta EventBusUtil, por lo que, cuando se demuestre el uso de AsyncEventBus más adelante, solo es necesario cambiar el método post () en TestMain.

Aquí están los códigos uno por uno.

Código de clase CustomEvent

package TestEventBus.event;public class CustomEvent {
    private int age;    public CustomEvent(int age){
   
           this.age = age;    }    public int getAge(){
   
           return this.age;    }}

Código de clase EventListener1.java

package TestEventBus.eventListeners;import TestEventBus.event.CustomEvent;import com.google.common.eventbus.Subscribe;import java.time.Instant;/** * @author fengjiale * @create 2019-09-04 13:40 * @desc 事件监听 **/public class EventListener1 {
   
       @Subscribe    public void test1(CustomEvent event){
   
           System.out.println(Instant.now() +"监听者1-->订阅者1,收到事件:"+event.getAge()+",线程号为:"+Thread.currentThread().getName());        try {
   
               Thread.sleep(3000);        } catch (InterruptedException e) {
   
               e.printStackTrace();        }    }    @Subscribe    public void test2(CustomEvent event){
   
           System.out.println(Instant.now() +"监听者1-->订阅者2,收到事件:"+event.getAge()+",线程号为:"+Thread.currentThread().getName());    }}

Código de clase EventListener2.java

package TestEventBus.eventListeners;import TestEventBus.event.CustomEvent;import com.google.common.eventbus.Subscribe;import java.time.Instant;import java.util.Date;/** * @author fengjiale * @create 2019-09-04 13:53 * @desc 事件监听 **/public class EventListener2 {
   
       @Subscribe    public void test(CustomEvent event){
   
           System.out.println(Instant.now() +",监听者2,收到事件:"+event.getAge()+",线程号为:"+Thread.currentThread().getName());        try {
   
               Thread.sleep(3000);        } catch (InterruptedException e) {
   
               e.printStackTrace();        }    }}

Como puede ver, las dos clases de escucha definen tres suscriptores en total, y los tres suscriptores se suscriben al mismo objeto de evento. Más adelante, observemos cómo los suscriptores manejan el evento después de recibir el evento en el modo de sincronización EventBus.

Código de herramienta:

package TestEventBus.util; import com.google.common.eventbus.AsyncEventBus;import com.google.common.eventbus.EventBus;import java.util.concurrent.Executor;/** * @author fengjiale * @create 2019-09-04 13:55 * @desc 事件总线工具类 **/public class EventBusUtil {
   
       private static EventBus eventBus;    private static AsyncEventBus asyncEventBus;    private static Executor executor = new Executor() {
   
           public void execute(Runnable command) {
   
               new Thread(command).start();        }    };    //双重锁单例模式    private static AsyncEventBus getAsynEventBus(){
   
           if(asyncEventBus==null){
   
               synchronized (AsyncEventBus.class){
   
                   if(asyncEventBus==null){
   
                       asyncEventBus = new AsyncEventBus(executor);                }            }        }        return asyncEventBus;    }    //双重锁单例模式    private static EventBus getEventBus(){
   
           if(eventBus==null){
   
               synchronized (EventBus.class){
   
                   if(eventBus==null){
   
                       eventBus = new EventBus();                }            }        }        return eventBus;    }    public static void post(Object event){
   
           getEventBus().post(event);    }    //异步方式发送事件    public static void asyncPost(Object event){
   
           getAsynEventBus().post(event);    }    public static void register(Object object){
   
           getEventBus().register(object);        getAsynEventBus().register(object);    } }

Código de prueba:

package TestEventBus; import TestEventBus.event.CustomEvent;import TestEventBus.eventListeners.EventListener1;import TestEventBus.eventListeners.EventListener2;import TestEventBus.util.EventBusUtil; import java.time.Instant; public class TestMain {
   
       public static void main(String[] args) {
   
           EventListener1 listener1 = new EventListener1();        EventListener2 listener2 = new EventListener2();        CustomEvent customEvent = new CustomEvent(23);        EventBusUtil.register(listener1);        EventBusUtil.register(listener2);        EventBusUtil.post(customEvent);        System.out.println(Instant.now() +",主线程执行完毕:"+Thread.currentThread().getName());    }}

Lo anterior es la clase de prueba. El objeto del detector de eventos se crea y se registra con EventBus, y el método de publicación síncrona de EventBus se llama para ejecutarse. Los resultados son los siguientes:

2019-09-04T09:05:35.420Z,监听者1-->订阅者1,收到事件:23,线程号为:main2019-09-04T09:05:38.480Z,监听者1-->订阅者2,收到事件:23,线程号为:main2019-09-04T09:05:38.480Z,监听者2,收到事件:23,线程号为:main2019-09-04T09:05:41.485Z,主线程执行完毕:main

Synchronous EventBus resume la ley: puede ver que el consumidor de cada evento se ejecuta utilizando el hilo de la persona que llama, y ​​solo se puede ejecutar el método de un suscriptor al mismo tiempo. Se puede ver que el método en Listener1 se ejecuta antes que el método en Listener2, que los suscriptores registrados en EventBus lo ejecutarán primero después de recibir el evento.

 

Luego pruebe el resultado del evento de envío asincrónico, abra el comentario anterior, cambie al método EventBusUtil.asyncPost (), el registro es el siguiente:

2019-09-04T09:12:14.010Z,监听者1-->订阅者2,收到事件:23,线程号为:Thread-22019-09-04T09:12:14.010Z,监听者2,收到事件:23,线程号为:Thread-32019-09-04T09:12:14.010Z,监听者1-->订阅者1,收到事件:23,线程号为:Thread-12019-09-04T09:12:24.014Z,主线程执行完毕:main

Ejecución asincrónica, tres suscriptores se ejecutan al mismo tiempo y se vuelve a abrir un nuevo hilo para que el consumidor de eventos realice sus propias tareas sin esperar el uno al otro.

Debido a la ejecución paralela aquí, hay suspensión en el método del suscriptor, por lo que el hilo principal también puede esperar 10 segundos. 

 

Cuarto, la diferencia entre EventBus y AsyncEventBus

El caso de prueba anterior es simple y muy ilustrativo.

EventBus: bus de eventos síncrono

1. Ejecución síncrona: después de enviar el evento, el remitente del evento esperará a que se ejecuten todos los consumidores del evento antes de regresar para continuar ejecutando el código detrás de él.

2. El remitente del evento y el consumidor del evento se ejecutarán en el mismo hilo, y el hilo de ejecución del consumidor depende del remitente.

3. Para varios suscriptores del mismo evento, el orden de recepción del evento es diferente. Quien se registre primero en EventBus lo ejecutará primero. Si dos suscriptores de la misma clase se registran juntos en EventBus, el orden de recepción de eventos está relacionado con el nombre del método.

AsyncEventBus: bus de eventos asincrónico

1. Ejecución asincrónica, el remitente del evento envía el evento de forma asincrónica, no espera a que el consumidor del evento lo reciba y ejecuta directamente el código detrás de él.

2. Al definir AsyncEventBus, se pasa un grupo de subprocesos en el constructor. Cuando el consumidor de eventos recibe un evento asincrónico, el consumidor obtendrá un nuevo hilo del grupo de hilos para realizar sus propias tareas.

3. Para múltiples suscriptores de un mismo evento, su orden de registro no tiene nada que ver con el orden en el que reciben el evento. Recibirán el evento al mismo tiempo, y todos ejecutarán sus tareas de forma asincrónica y concurrente en un nuevo hilo.

 

Blog de referencia


 

 

 

Supongo que te gusta

Origin blog.csdn.net/CharlesYooSky/article/details/105812797
Recomendado
Clasificación