我有一个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响应?
我考虑两个选择:
将errors对象设置为初始XmlReceivedEvent并在处理完成后检索它:
public class RequestHandler {
@RequestMapping
public Errors handleRequest(String xmlData) {
XmlReceivedEvent event = new XmlReceivedEvent(xmlData);
eventBus.post(event);
...
return event.getErrors();
}
}
但是,在这种情况下,我必须将错误对象传递给链中的每个事件,以使其可用于 Validator 以使用实际数据填充它。
从 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();
}
}
但是,不幸的是, RequestHandler 是一个Spring无状态服务(单例),所以我想避免在类字段中保存任何数据。
欣赏任何想法。
答案 0 :(得分:10)
如果你想要这样的工作流程,你不应该使用番石榴EventBus
。 EventBus
专门用于允许事件发布给订阅者,而事件海报不知道或关心这些订阅者是什么......因此,您无法将结果返回给订阅者的活动海报。< / p>
听起来我觉得你应该在这里做一些更简单的事情,比如注入预处理器,持久化和验证器并直接调用他们的方法。