首页 > 其他分享 >Google Guava:EventBus

Google Guava:EventBus

时间:2023-12-26 14:31:35浏览次数:26  
标签:google springframework Google common import EventBus Guava com eventBus

EventBus是Guava中对于事件发布订阅功能的实现,是设计模式中的发布/订阅模式的一种实现方案。

功能概括:

通过eventBus.register注册订阅者,通过eventBus.post方法发布事件,然后根据发布事件的类型(classType),执行所有订阅者中被@Subcribe注解标记的且参数类型一致的方法,从而实现发布、订阅功能。

源码解读:

源码基于如下版本解析:

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

 


 

1. 通过eventBus.register()方法注册订阅者

Google Guava:EventBus_工具类

2. 将该订阅者注册到该eventBus中,源码见findAllSubcribers(listener)方法。在这个过程中,会查找到被注册类中被@Subcribe注解标记的方法,并将这些方法按照 入参类型,添加到Multimap<class<?>, Subcriber>中

Google Guava:EventBus_工具类_02

 


 

3. 通过eventBus.post()方法发布事件,根据事件类型找到所有对应subcriber,遍历;然后由eventBus中的线程池执行订阅者中入参类型匹配的方法。

Google Guava:EventBus_Java_03

简单实用示例:

在springboot中,使用自动注入的方式来实现

目录结构:

Google Guava:EventBus_工具类_04

代码如下:

package com.example.demo.eventbus.config;

import com.google.common.eventbus.EventBus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 注入eventBus bean
 *
 */
@Configuration
public class EventBusConfig {

    @Bean("eventBus")
    public EventBus eventBus() {
        return new EventBus("demo");
    }
}


package com.example.demo.eventbus.listener;

import com.google.common.eventbus.EventBus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * 注册eventListener
 *
 */
@Component
public class ApplicationListenerRegister implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private EventBus eventBus;

    @Autowired
    private ConfigurableApplicationContext context;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        Map<String, IEventListener> listenerMap = context.getBeansOfType(IEventListener.class);
        if (!CollectionUtils.isEmpty(listenerMap)) {
            for (Map.Entry<String, IEventListener> entry : listenerMap.entrySet()) {
                eventBus.register(entry.getValue());
                System.out.println("eventListener registed: " + entry.getValue().getClass());
            }
        }
    }
}


package com.example.demo.eventbus.listener;

/**
 * 事件监听者接口
 *
 */
public interface IEventListener {
}


package com.example.demo.eventbus.listener;

import com.google.common.eventbus.Subscribe;
import org.springframework.stereotype.Component;

/**
 * 监听Integer
 *
 */
@Component
public class ListenerInt implements IEventListener{

    @Subscribe
    public int call(Integer num) {
        System.out.println("ListenerInt call(): " + num);
        return num;
    }

}


package com.example.demo.eventbus.listener;

import com.google.common.eventbus.Subscribe;
import org.springframework.stereotype.Component;

/**
 * 监听字符串事件
 *
 */
@Component
public class ListenerStr implements IEventListener{

    @Subscribe
    public String call(String str) {
        System.out.println("ListenerStr call() : " + str);
        return str;
    }

    @Subscribe
    public String call2(String str) {
        System.out.println("ListenerStr call2() : " + str);
        return str;
    }
}


package com.example.demo.eventbus;

import com.google.common.eventbus.EventBus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * eventBus测试
 *
 */
@RestController
@RequestMapping("/event")
public class EventBusTestController {


    @Autowired
    private EventBus eventBus;

    @GetMapping("/eventTest")
    public void eventTest() {
        System.out.println("eventTest started");
        eventBus.post("string test");

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        eventBus.post(111);
        System.out.println("eventTest end");
    }
}

运行结果:

 

 

Google Guava:EventBus_Java_05

 

附带介绍下Java  guava工具包:

 

Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你的JAVa代码更加优雅,更加简洁,让你工作更加轻松愉悦。下面我们就开启优雅Java编程学习之旅!

  项目相关信息:

  官方首页:http://code.google.com/p/guava-libraries  

官方下载:http://code.google.com/p/guava-libraries/downloads/list  

官方文档:http://docs.guava-libraries.googlecode.com/git/javadochttp://www.ostools.net/apidocs/apidoc?api=guava

  源码包的简单说明:
  com.google.common.annotations:普通注解类型。
  com.google.common.base:基本工具类库和接口。
  com.google.common.cache:缓存工具包,非常简单易用且功能强大的JVM内缓存。
  com.google.common.collect:带泛型的集合接口扩展和实现,以及工具类,这里你会发现很多好玩的集合。
  com.google.common.eventbus:发布订阅风格的事件总线。
  com.google.common.hash: 哈希工具包。
  com.google.common.io:I/O工具包。
  com.google.common.math:原始算术类型和超大数的运算工具包。
  com.google.common.net:网络工具包。
  com.google.common.primitives:八种原始类型和无符号类型的静态工具包。
  com.google.common.reflect:反射工具包。
  com.google.common.util.concurrent:多线程工具包。

  类库使用手册:

  一. 基本工具类:让使用Java语言更令人愉悦。

  1. 使用和避免 null:null 有语言歧义, 会产生令人费解的错误, 反正他总是让人不爽。很多 Guava 的工具类在遇到 null 时会直接拒绝或出错,而不是默默地接受他们。
  2. 前提条件:更容易的对你的方法进行前提条件的测试。
  3. 常见的对象方法: 简化了Object常用方法的实现, 如 hashCode() 和 toString()。
  4. 排序: Guava 强大的 "fluent Comparator"比较器, 提供多关键字排序。
  5. Throwable类: 简化了异常检查和错误传播。

  二. 集合类:集合类库是 Guava 对 JDK 集合类的扩展, 这是 Guava 项目最完善和为人所知的部分。

  1. Immutable collections(不变的集合): 防御性编程, 不可修改的集合,并且提高了效率。
  2. New collection types(新集合类型):JDK collections 没有的一些集合类型,主要有:multisets,multimaps,tables, bidirectional maps等等
  3. Powerful collection utilities(强大的集合工具类): java.util.Collections 中未包含的常用操作工具类
  4. Extension utilities(扩展工具类): 给 Collection 对象添加一个装饰器? 实现迭代器? 我们可以更容易使用这些方法。

  三. 缓存: 本地缓存,可以很方便的操作缓存对象,并且支持各种缓存失效行为模式。

  四. Functional idioms(函数式): 简洁, Guava实现了Java的函数式编程,可以显著简化代码。

  五. Concurrency(并发):强大,简单的抽象,让我们更容易实现简单正确的并发性代码。

  1. ListenableFuture(可监听的Future): Futures,用于异步完成的回调。
  2. Service: 控制事件的启动和关闭,为你管理复杂的状态逻辑。

  六. Strings: 一个非常非常有用的字符串工具类: 提供 splitting,joining, padding 等操作。

  七. Primitives: 扩展 JDK 中未提供的对原生类型(如int、char等)的操作, 包括某些类型的无符号的变量。

  八. Ranges: Guava 一个强大的 API,提供 Comparable 类型的范围处理, 包括连续和离散的情况。

  九. I/O: 简化 I/O 操作, 特别是对 I/O 流和文件的操作, for Java 5 and 6.

  十. Hashing: 提供比 Object.hashCode() 更复杂的 hash 方法, 提供 Bloom filters.

  十一. EventBus: 基于发布-订阅模式的组件通信,但是不需要明确地注册在委托对象中。

  十二. Math: 优化的 math 工具类,经过完整测试。

  十三. Reflection: Guava 的 Java 反射机制工具类。

标签:google,springframework,Google,common,import,EventBus,Guava,com,eventBus
From: https://blog.51cto.com/u_6346066/8983387

相关文章

  • Auto Image Attributes Pro v4.4:优化图片SEO,解锁Google图片流量
    AutoImageAttributesProv4.4已注册–WordPress插件AutoImageAttributesProv4.4:优化图片SEO,解锁Google图片流量一、插件概述在数字时代,图像已成为网站内容不可或缺的一部分。然而,仅仅上传图像并不足以吸引搜索引擎的注意。为了从图像中获得最大的SEO价值,您需要一款功......
  • 测试开发 | 语音助手技术:Siri、Alexa、Google Assistant的背后
    语音助手技术作为人工智能领域的一项重要应用,已经在我们的日常生活中扮演了越来越重要的角色。Siri、Alexa、GoogleAssistant等知名语音助手系统,不仅成为我们的智能助手,更是科技发展和人机交互的代表。本文将深入研究这些语音助手技术的背后,揭示它们的工作原理和对社会的深远影响......
  • SRE Google运维解密 4-9章
    第四章服务质量目标如果不详细了解服务中各种行为的重要程度,并且不去度量这些行为的正确性的话,就无法正确运维这个系统,更不要说可靠低运维了。那么,不管是对外服务,还是内部API,我们都需要制定一个针对用户的服务质量目标,并且努力去达到这个质量目标。服务质量指标(SLI)服务质量目......
  • Guava中的多值映射Multimap的深入分析
    第1章:引言今天小黑要重点介绍的是Guava中超实用的一个工具:Multimap。Multimap这个东西,其实可以看作是Map的一个加强版。在Java标准库中,一个key只能对应一个value,但在实际开发中,我们经常会遇到一个key对应多个value的情况,这时候就有点力不从心了。比如,假设咱们要管理一个学校的......
  • Guava的TypeToken在泛型编程中的应用
    第1章:引言在Java世界里,泛型是个相当棒的概念,能让代码更加灵活和类型安全。但是,泛型也带来了一些挑战,特别是当涉及到类型擦除时。这就是TypeToken大显身手的时候!作为Java程序员的咱们,都知道泛型可以让代码更加通用,但同时也可能会导致一些类型信息在运行时丢失,这就是所谓的类型擦......
  • Guava自加载缓存LoadingCache使用指南
    第1章:引言大家好,我是小黑,今天我们来聊聊缓存。在Java世界里,高效的缓存机制对于提升应用性能、降低数据库负担至关重要。想象一下,如果每次数据请求都要跑到数据库里取,那服务器岂不是要累趴了?这时候,缓存就显得尤为重要了。那么,怎么实现一个既高效又好用的缓存呢?别急,咱们今天的主......
  • keto ory 团队开源的google zanzibar 实现
    ory公司在认证以及授权方面开源了不少东西,keto就是一个googlezanzibar的开源实现代码基于golang开发,同时也是提供了restapi以及grpc能力,同时还支持一个OPL的权限模型语言说明类似的开源实现有不少,permify也是一个,还有openfga,都是值得研究学习的参考资料https://gith......
  • permify google zanzibar 类似的开源授权服务实现
    permifygooglezanzibar类似的开源授权服务实现,openfga也是一个类似的开源实现参考架构从下图可以看出permify主要包含了四个组件,PermissionServer,RelationshipServer,SchemaServer,WatchServer说明目前不少开源的授权认证方案,都会基于配置定义的模式开发(schema)比较灵活......
  • ReplaceGoogleCDN替换打不开的网页资源
    插件安装地址:ChromeFirefoxEdge背景在日常的网络浏览中,我们经常访问各种网站,其中包括大量使用了GoogleCDN(ContentDeliveryNetwork)的网页。虽然GoogleCDN在提供稳定、高效的内容分发方面表现出色,但在某些情况下,由于网络限制或其他原因,我们可能会遇到加载缓慢或无法访......
  • Java异常处理神器:Guava Throwables类
    第一章:Guava库简介Guava由Google开发,它提供了大量的核心Java库,例如:集合、缓存、原生类型支持、并发库、通用注解、字符串处理和I/O操作等。这些功能在日常的Java开发中超级常用,而且Guava的设计哲学是简洁高效,这让咱们的代码不仅更加优雅,而且更加易于维护和阅读。尤其是在异常处......