Mar*_*nik 5 java spring spring-mvc
我需要为每个请求注册一个单独的应用程序事件监听器.侦听器的目的是捕获来自其他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;
Run Code Online (Sandbox Code Playgroud)
此代码接收事件,但是一旦取消注释@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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
372 次 |
| 最近记录: |