Guava EventBus:如何从事件处理程序返回结果

4
我是一名有用的助手,可以为您翻译文本。

我有一个网络服务,可以接收来自另一个系统的XML事件,并使用特定的工作流程进行处理,然后将潜在错误列表作为HTTP响应发送回去。

事件处理工作流程由几个处理程序(例如:预处理器持久化器验证器)组成,使用Guava's EventBus实现。处理程序相互发送事件,类似于以下内容:

public class RequestHandler {

    @RequestMapping
    public Errors handleRequest(String xmlData) {
        eventBus.post(new XmlReceivedEvent(xmlData));
        ...
        return errors; // how to get errors object from the last handler in chain ? 
    }
}

public class Preprocessor {

    @Subscribe
    public void onXmlReceived(XmlReceivedEvent event) {
       // do some pre-processing
       ...  
       eventBus.post(new PreprocessingCompleteEvent(preprocessingResult)); 
    }
}

public class Persister {

    @Subscribe
    public void onPreprocessingComplete(PreprocessingCompleteEvent event) {
       // do some persistence stuff
       ...    
       eventBus.post(new PersistenceCompleteEvent(persistenceResult)); 
    }
}

public class Validator {

    @Subscribe
    public void onPersistenceComplete(PersistenceCompleteEvent event) {
       // do validation
       ...    
       eventBus.post(new ValidationCompleteEvent(errors)); // errors object created, should be returned back to the RequestHandler 
    }
}

问题是:如何从验证器处理程序深度返回处理结果到起始点(请求处理程序),以便用户可以接收HTTP响应?
我考虑了两个选项:
  1. Set errors object to the initial XmlReceivedEvent and retrieve it after processing complete:

    public class RequestHandler {
    
        @RequestMapping
        public Errors handleRequest(String xmlData) {
            XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
            eventBus.post(event);
            ...
            return event.getErrors(); 
        }
    }
    
然而,在这种情况下,我将不得不将错误对象传递给链中的每个事件,以使其对验证器可用,并填充实际数据。
  1. Subscribe RequestHandler to ValidationCompleteEvent from Validator with populated errors object inside.

    public class RequestHandler {
    
        private Errors errors;
    
        @RequestMapping
        public Errors handleRequest(String xmlData) {
            XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
            eventBus.post(event);
            ...
            return this.errors; // ??? 
        }
    
        @Subscribe
        public void onValidationComplete(ValidationCompleteEvent event) {
            this.errors = event.getErrors();
        }
    }
    

但是,不幸的是,RequestHandler是一个Spring无状态服务(单例),所以我想避免在类字段中保存任何数据。

感谢任何想法。

1个回答

10
如果您想要这样的工作流程,就不应该使用Guava的EventBusEventBus 的设计目的是允许将事件发布给订阅者,而无需事件发布者知道或关心这些订阅者是谁...因此,您无法从订阅者那里向事件发布者返回结果。
在我看来,您应该在这里做一些更加直接的事情,比如注入您的预处理器、持久器和验证器,并直接调用它们的方法。

谢谢,这听起来很合理。但是,我担心创建这样一个神对象,它持有对所有其他应用程序组件的引用。这可能非常难以测试,你怎么看? - stoweesh
@stoweesh:我不知道,从你所描述的来看,它对我来说并不像是一个全能对象。如果它确实成为了全能对象,一般的做法是找到逻辑上相关的操作并将其提取到另一个类中。当然,使用接口和注入服务,以便可以使用虚拟实现进行简单的测试。 - ColinD

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