[英]Request-scoped ApplicationEventListener fails to receive events
我需要为每个请求注册一个单独的应用程序事件监听器。 侦听器的目的是捕获来自其他REST请求的事件,同时阻止侦听器的请求等待所有必需的事件进入。
我有这样的代码:
@Component
// @Scope(WebApplicationContext.SCOPE_REQUEST)
public static class WhistleEventListener implements ApplicationListener<WhistleEvent> {
volatile Consumer<WhistleEvent> handler;
@Override
public void onApplicationEvent(WhistleEvent we) {
final Consumer<WhistleEvent> h = handler;
if (h != null) h.accept(we);
}
}
@Autowired WhistleEventListener whistleEventListener;
此代码接收事件,但是一旦取消注释@Scope
注释,它就会停止接收事件。
是否支持请求范围的应用程序事件侦听器,它们应该可以工作吗? 如果是这样,我可以做些什么让我的听众工作吗?
我怀疑你对应用程序事件调度机制有一个误解:事件是针对bean 定义而不是bean 实例调度的,并且每个bean定义现在被解析为一个实例,并且在上下文中被解析为事件发布。 这意味着您的事件将仅发送到属于发布事件的请求的请求范围的bean,但您希望通知所有当前请求的侦听器。
更一般地,范围的目的是隔离包含单独的bean实例的范围实例。 如果您不想要隔离,则应使用没有单独实例的范围,例如应用程序范围。
也就是说,要将事件分派给其他范围实例,您必须自己进行调度,例如:
@Component
public class WhistleEventMediator implements ApplicationListener<WhistleEvent> {
// TODO: make thread safe
final Set<Consumer<WhistleEvent>> consumers;
void subscribe(Consumer<WhistleEvent> c) { ... }
void unsubscribe(Consumer<WhistleEvent> c) { ... }
@Override public void onApplicationEvent(WhistleEvent we) {
// delegate to subscribed consumers
}
}
@Component
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class WhateverBean implements Consumer<WhistleEvent> {
@Inject
WhistleEventMediator mediator;
@PostConstruct
void init() {
mediator.subscribe(this);
}
@PreDestroy
void destroy() {
mediator.unsubscribe(this);
}
// handle whistle event
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.