轻量级消息总线库

17

我即将开始一个小型的Java(实际上是GWT)项目,目前处于“信息收集”阶段。

问题:是否有用Java编写的轻量级消息总线库?

我的要求也很轻量级 :-)

  1. 异步(无需同步)
  2. 多播和点对点
  3. 没有严格的消息排序
  4. 消息“包裹”最好由消息总线“拥有”(即在生命周期管理方面)
  5. 本地化交付(即不是进程间或节点间交付)

更新:看起来GWT现在支持一个集成的"事件总线"


你可以在这里查看 https://github.com/javaplugs/minibus,它是一个非常轻量级和简单的事件总线。 - rumatoest
5个回答

12

1
你也可以查看 https://github.com/bennidi/mbassador。它非常轻量级,快速且使用弱引用。 - bennidi
@bennidi:你应该将其作为新答案发布,而不是使用评论。 - Aaron Digulla

10

我知道这是一个旧问题,但我认为更现代的解决方案是使用Guava事件总线(虽然我不确定它是否适用于GWT,但您的标题和标签都没有提到GWT)。

实际上,我有一个自定义的RabbitMQ简单消息容器,它会自动创建队列绑定,并在接收到消息后将其分派到Guava事件总线。它非常优雅,并且可以很好地扩展。

您可以轻松使用DI框架来注册订阅者。对于Spring,我创建了一个BeanPostProcessor,它会自动使用@Subscribe注册bean。

以下是Spring BeanPostProcessor:

package com.snaphop.spring;

import java.lang.reflect.Method;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

@Component
public class EventBusBeanPostProcessor implements BeanPostProcessor {

    private EventBus eventBus;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (isApplicable(bean)) {
            eventBus.register(bean);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    protected boolean isApplicable(Object bean) {
        for(Method m : bean.getClass().getMethods()) {
            if (m.isAnnotationPresent(Subscribe.class))
                return true;
        }
        return false;
    }

    @Autowired
    public void setEventBus(EventBus eventBus) {
        this.eventBus = eventBus;
    }

}

我相信在Guice中做类似的事情是很简单的。


我曾尝试使用Google Guava的事件总线,但因其对侦听器使用强引用而陷入困境。我想在Spring环境中使用它,并使用后处理器将所有bean都塞进去。但这在Guava中行不通。于是我创建了自己的解决方案,托管在GitHub上https://github.com/bennidi/mbassador。现在它非常稳定(已在生产中使用半年),比Google Bus更快。它还提供了更多功能,但使用起来同样简单。 - bennidi
我也做了类似的实现,主要是因为Guava使用JULI,而我不喜欢它捕获异常。我得去看看你的实现... 我还注意到Guava使用了Class<?>的集合,这可能会导致PermGen泄漏。 - Adam Gent
1
“collection of Class<?> could lead to permgen leaks” 是什么意思?此外,我非常感谢有关 MBassador 的反馈。如果它缺少您需要的功能,您可以在 GitHub 上提交问题。 - bennidi
实际上,在使用Guava EventBus时,不需要显式检查@Subscribe注释:https://github.com/google/guava/wiki/EventBusExplained#what-happens-if-i-register-a-listener-without-any-handler-methods - Alex

5
如果您已经在使用Spring,那么一个方便的、有点隐藏的Spring特性是ApplicationEventMulticaster接口,它是一个非常简单的API,用于发布和订阅应用程序生成的事件。实现使用TaskExecutor框架,这意味着它们可以根据需要进行同步或异步。此外,每个ApplicationContext都有一个publishEvent方法,因此轻松设置为Spring管理的类。

所以,如果您已经使用Spring,则无需另一个实用程序来执行此操作,因为它已经内置了。


2
+1:非常感谢。虽然我不会使用Spring,但我始终珍视好的信息。 - jldupont

0

不确定它是否真的很轻量级。但它确实符合您的其余描述:ActiveMQ


@reinier:我知道基于AMQP的解决方案:(1)不太轻量级(当然这是相对的;-) (2)不太适用于基于GWT的项目。 - jldupont
@jldupont:啊,对了……所有的东西都必须在浏览器的同一个进程中运行,是吗?那么,在这种情况下,请忽略这个想法;^) - Toad
@reinier:那么删除它吧,因为你很可能会在某些时候得到一些踩票(不是来自我)。 - jldupont
3
他们倾向于这样做。;^) 尽管我的错误解决方案对于其他可能提出相同回应的人增加了对话的内容。 - Toad
@reinier:那就按你的意愿吧。干杯 :-) - jldupont
您只需要这个 GWT 连接器。http://code.google.com/p/gwt-activemq/ - MarianP

0
也许你可以尝试一些基于Jabber(XMPP)的解决方案。Openfire怎么样?

@marcospereira:你是认真的吗?并不是因为我不会经常点踩,就可以在这里滥用! - jldupont
jldupont:是的,我很认真。我不明白为什么你认为我的评论是一种辱骂。如果你认为这是错误的解决方案,请提供一些理由。;-) - marcospereira
实际上XMPP很酷,但可能有太多的开销。 - Leo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接