4

我有一个 Web 服务,它从另一个系统接收 xml 事件,使用特定的工作流程处理它们,并将潜在错误列表作为 HTTP 响应发送回。

事件处理工作流由几个使用Guava 的 EventBus实现的处理程序(比如说: PreprocessorPersisterValidator )组成。处理程序相互发送事件。像这样的东西:

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 
    }
}

问题是:如何将Validator处理程序的处理结果深度返回到起点(RequestHandler),以便用户可以接收到 HTTP 响应?

我考虑两种选择:

  1. 将错误对象设置为初始 XmlReceivedEvent 并在处理完成后检索它:

    public class RequestHandler {
    
        @RequestMapping
        public Errors handleRequest(String xmlData) {
            XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
            eventBus.post(event);
            ...
            return event.getErrors(); 
        }
    }
    

但是,在这种情况下,我必须将错误对象传递给链中的每个事件,以使其可供Validator使用真实数据填充它。

  1. 将RequestHandlerValidator订阅到ValidationCompleteEvent ,其中包含填充的错误对象。

    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 无状态服务(单例),所以我想避免在类字段中保存任何数据。

欣赏任何想法。

4

1 回答 1

10

If you want a workflow like that, you shouldn't be using a Guava EventBus for it. EventBus is specifically intended to allow events to be posted to subscribers without the event poster knowing or caring about what those subscribers are... as such, you can't return results to the poster of an event from subscribers.

It sounds to me like you should be doing something much more straightforward here, like injecting your preprocessor, persister and validator and calling their methods directly.

于 2012-04-25T13:46:35.143 回答