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

时间:2012-04-25 05:22:03

标签: java events event-handling guava

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

事件处理工作流由几个处理程序组成(比方说:预处理程序 Persister Validator ),使用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 
    }
}

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

我考虑两个选择:

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

    public class RequestHandler {
    
        @RequestMapping
        public Errors handleRequest(String xmlData) {
            XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
            eventBus.post(event);
            ...
            return event.getErrors(); 
        }
    }
    
  2. 但是,在这种情况下,我必须将错误对象传递给链中的每个事件,以使其可用于 Validator 以使用实际数据填充它。

    1. Validator 中将 RequestHandler 订阅到 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();
          }
      }
      
    2. 但是,不幸的是, RequestHandler 是一个Spring无状态服务(单例),所以我想避免在类字段中保存任何数据。

      欣赏任何想法。

1 个答案:

答案 0 :(得分:10)

如果你想要这样的工作流程,你不应该使用番石榴EventBusEventBus专门用于允许事件发布给订阅者,而事件海报不知道或关心这些订阅者是什么......因此,您无法将结果返回给订阅者的活动海报。< / p>

听起来我觉得你应该在这里做一些更简单的事情,比如注入预处理器,持久化和验证器并直接调用他们的方法。