2015-09-04 47 views
3

我需要從由rootContext管理的bean向由mvcContext管理的bean發送消息/事件。上下文之間的春天交流

我的web應用程序的組成如下: - 在RootContext(的applicationContext):數據庫,道豆類,豆類服務,安全等 - 一個MVC上下文(web.xml中的servlet條目):管理控制器,restcontroller和端點(websocket)

每次創建一個新行(在服務bean中),我都需要向所有活動的websocket會話進行廣播。

我在服務bean中使用ApplicationEventPublisherAware來發布目標bean中的事件和@EventListener來處理它:但事件不會在rootContext之外廣播。

如果我移動mvcContext中的服務bean,這沒關係 但是我需要rootContext中的服務bean,因爲另一個組件使用它(其他servlet(web.xml中的servlet條目); spring-batch任務;等等..)

我該怎麼辦?

PS:遺憾的英語不好

+0

正確,因爲父級不瞭解子上下文。另一種方式將工作。您可以在您的孩子中創建一個註冊爲根節點的ApplicationListener,然後將事件傳播給子節點。 –

+0

感謝您的確認。但是,在子環境中註冊服務bean還是在子環境中實現ApplicationListener並傳播事件之間的最佳方式是什麼? – chtibob69

回答

0

您可以創建在自己註冊爲一個監聽父上下文和在接收事件的孩子上下文中的豆,它發佈到孩子上下文。

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放在子上下文中,應該使它能夠接收來自父類的事件並將它們廣播到子上下文中。

注意:這可能有一個缺陷,那就是你可能會陷入事件循環。當孩子再次發佈給父母時。因此,您可能需要針對該解決方案 ....

+0

此解決方案將導致'java.lang.StackOverflowError',因爲子上下文將發送事件給父上下文 - >父上下文發送給子上下文 - >子上下文發送給父母..... –

+0

這就是我已經提到過的答案... –

+0

對不起,我錯過了:D –