How to bridge Spring Application Context events to an other context

前端 未结 5 828
深忆病人
深忆病人 2021-01-07 22:58

I have a Spring web application with two contexts: one (applicationContext) built by ContextLoaderListener and a second (webContext) b

相关标签:
5条回答
  • 2021-01-07 23:20

    I think the actual answer is that you may want to configure your app differently (so that you only have one context) I think in your web.xml you need to do something like this :

    <servlet>
        <servlet-name>example</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>               
                classpath:/META-INF/applicationSpringConfig.xml
            </param-value>
        </init-param> 
    </servlet>
    

    But to answer the deeper question. Someone else points out that you can use includes in your spring file (indeed in the above you can have more than one springconfig specified in your dispatcher servlet). But when you include other context files you do not share instances of beans, only definitions.

    Modularising Spring applications has been the only real downside of spring in comparison with EJB etc. That led spring into using OSGi. And the answer to your underlying question of how to share spring context, officially you share spring bean instances between contexts using OSGi (spring dm)

    0 讨论(0)
  • 2021-01-07 23:28

    As stated in documentation for the spring framework the simple ApplicationEvent mechanism is only designed to be used within the same application context, I am not aware that it is possible to propagate events to child contexts.

    If you need a more advanced solution you might look into using a more enhanced solution like Java Message Service or Spring Integration.

    http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-functionality-events

    0 讨论(0)
  • 2021-01-07 23:35

    Try moving the event publisher to the web context file, where it should have visibility over the whole application context. A similar issue occurs when configuring method security in the parent application context. The parent application context (loaded by ContextLoaderListener) isn't aware of the child (web) context.

    You can also use a single application context for the entire application if you don't really need the parent-child relationship between the two. Often it just gets in the way and it is easier if all beans were defined in the same space.

    0 讨论(0)
  • 2021-01-07 23:40

    I had the same problem, solved mine by moving the beans creating the event to web-context. However you can solve your problem by manually wiring your event listener, something like this (this code is not compiled therefore it is untested):

    @Component    
    public class BeanInWebContext implements ApplicationListener<SomeEvent> {
    
        @Autowired
        private ApplicationContext webContext;
    
        @PostConstruct
        public void registerAsListener() {
            // get parent context
            AbstractApplicationContext appContext = (AbstractApplicationContext) webContext.getParent();
            // register self as a listener, this method is in AbstractApplicationContext
            appContext.addApplicationListener(this);
        }
    
        @Override
        public void onApplicationEvent(SomeEvent event) {
        }
    
    }
    
    0 讨论(0)
  • 2021-01-07 23:46

    We can use the import tag to import/bridge the 2 different contexts created in a way the visibility of the events/beans are available and shared.

    <import resource="applicationContext_name.xml"/>
    

    In this import the context xml which is configured to be created from ContextLoaderListener in the context xml of the DispatcherServlet.

    0 讨论(0)
提交回复
热议问题