如何将 Spring 应用程序上下文事件桥接到其他上下文

2022-09-02 21:53:12

我有一个具有两个上下文的Spring Web应用程序:一个()由构建,另一个由构建()。applicationContextContextLoaderListenerwebContextDispatcherServlet

里面是一个豆子(),它点燃了春天的上下文事件。applicationContextorg.springframework.security.authentication.DefaultAuthenticationEventPublisher

但事件的接收器在 中定义。并且该接收者未获得事件。(如果将接收器用于测试目的,那么它会得到事件,但我不能这样做,因为我需要s来实现其功能。webContextapplicationContextwebContext

所以我的问题是,如何将事件从到?applicationContextwebContext


答案 1

我遇到了同样的问题,通过将创建事件的bean移动到Web上下文来解决我的问题。但是,您可以通过手动连接事件侦听器来解决您的问题,如下所示(此代码未编译,因此未经测试):

@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) {
    }

}

答案 2

我认为实际的答案是,您可能希望以不同的方式配置您的应用程序(以便您只有一个上下文),我认为在您的Web中.xml您需要执行以下操作:

<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>

但要回答更深层次的问题。其他人指出,您可以在 spring 文件中使用 include(实际上,在上面,您可以在调度程序 servlet 中指定多个 springconfig)。但是,当您包含其他上下文文件时,您不共享Bean的实例,只共享定义。

与EJB等相比,模块化弹簧应用一直是弹簧唯一真正的缺点。这导致了使用OSGi的春天。对于如何共享弹簧上下文的基本问题的答案,您正式使用OSGi(spring dm)在上下文之间共享弹簧豆实例