【问题标题】:Spring communication between context上下文之间的Spring通信
【发布时间】:2015-12-01 00:40:28
【问题描述】:

我需要将消息/事件从 rootContext 管理的 bean 发送到 mvcContext 管理的 bean。

我的 webapp 由以下部分组成: - RootContext(applicationContext):数据库、dao beans、service beans、security等 - mvc-context(web.xml 中的 servlet 条目):管理控制器、restcontroller 和端点(websocket)

每次(在服务 bean 中)创建新行时,我都需要向所有活动的 websocket 会话进行广播。

我在服务 bean 中使用 ApplicationEventPublisherAware 来发布事件,并在目标 bean 中使用 @EventListener 来处理它:但该事件并未在 rootContext 之外广播。

如果我在 mvcContext 中移动服务 bean 就可以了 但我需要 rootContext 中的服务 bean,因为另一个组件使用它(其他 servlet(web.xml 中的 servlet 条目);spring-batch 任务;等等...)

我该怎么办?

PS : 抱歉英语不好

【问题讨论】:

  • 正确,因为父级对子上下文一无所知。反过来也行。您可以在您的孩子中创建一个 bean,将其作为 ApplicationListener 注册到根上下文,然后将事件传播到子上下文。
  • 感谢您的确认。但是,在子上下文中注册服务 bean 或在子上下文中实现 ApplicationListener 并传播事件之间的最佳方式是什么?

标签: java spring spring-mvc events


【解决方案1】:

您可以在子上下文中创建一个 bean,将自己注册为父上下文的侦听器,并在收到事件后将其重新发布到子上下文。

public class ContextBridgingApplicationListener implements ApplicationListener, ApplicationEventPublisherAware, ApplicationContextAware, SmartInitializingSingleton {

    private ApplicationContext context;
    private ApplicationEventPublisher publisher;

    public void afterSingletonsInstantiated() {
        ApplicationContext parent = context.getParent();
        if (parent != null && parent instanceof ConfigurableApplicationContext) {
            ((ConfigurableApplicationContext) parent).addApplicationListener(this);
        }
    }

    public void onApplicationEvent(ApplicationEvent evt) {
        this.publisher.publishEvent(evt);
    }

    // Setters ommitted

}

尚未对其进行测试,或多或少是从我的头顶输入的。但是将这个 bean 放在子上下文中,应该使它能够从父上下文接收事件并将它们广播到子上下文。

注意: 这可能存在一个缺陷,那就是您可能会陷入事件循环。随着孩子再次向父母发布。所以你可能需要一个解决方案 ....

【讨论】:

  • 这个解决方案会导致java.lang.StackOverflowError,因为子上下文会将事件发送到父上下文->父上下文发送到子上下文->子上下文发送到父......
  • 对不起,我错过了:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2018-01-22
  • 1970-01-01
  • 2018-02-18
  • 2020-04-12
  • 1970-01-01
  • 2012-09-30
相关资源
最近更新 更多