我有一个包含两个上下文的Spring Web应用程序:一个(applicationContext
)由ContextLoaderListener
构建,另一个(webContext
)由DispatcherServlet
构建。
在applicationContext
内是一个bean(org.springframework.security.authentication.DefaultAuthenticationEventPublisher
),用于触发spring上下文事件。
但事件的接收者在webContext
中定义。那个接收器没有得到这个事件。 (如果在applicationContext
中将接收器用于测试目的,那么它就会得到事件,但我不能这样做,因为我需要webContext
来实现它的功能。)
所以我的问题是,如何将事件从applicationContext
桥接到webContext
?
答案 0 :(得分:9)
我有同样的问题,通过将创建事件的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) {
}
}
答案 1 :(得分:4)
我认为实际的答案是您可能希望以不同方式配置您的应用程序(这样您只有一个上下文) 我想在你的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文件中使用includes(事实上在上面你可以在你的调度程序servlet中指定多个springconfig)。 但是当你包含其他上下文文件时,你不共享bean的实例,只有定义。
与EJB等相比,模块化Spring应用程序是春天唯一真正的缺点。这导致了使用OSGi。 关于如何共享spring上下文的基本问题的答案,正式你使用OSGi(spring dm)在上下文之间共享spring bean实例
答案 2 :(得分:3)
尝试将事件发布者移动到Web上下文文件,在该文件中,它应该可以看到整个应用程序上下文。 configuring method security in the parent application context时出现类似问题。父应用程序上下文(由ContextLoaderListener
加载)不知道子(web)上下文。
如果您真的不需要两者之间的父子关系,也可以为整个应用程序使用单个应用程序上下文。通常情况下它会阻碍,如果所有bean都在同一个空间中定义,那就更容易了。
答案 3 :(得分:3)
正如spring框架的文档中所述,简单的ApplicationEvent机制仅设计用于同一应用程序上下文中,我不知道可以将事件传播到子上下文。
如果您需要更高级的解决方案,可以考虑使用更强大的解决方案,如Java Message Service或Spring Integration。
答案 4 :(得分:0)
我们可以使用import标签导入/桥接以事件/ bean的可见性可用和共享的方式创建的两个不同的上下文。
<import resource="applicationContext_name.xml"/>
在此导入中,配置为在DispatcherServlet的上下文xml中从ContextLoaderListener创建的上下文xml。