我有一个关于Spring的ApplicationListener在父子上下文方面的性质的问题。假设您创建了一个父上下文,该上下文创建了一个单例并注册为ApplicationListener的bean。然后,稍后使用父上下文创建子上下文。当关闭子上下文时,Spring将发出ContextClosedEvent。此事件是否传播到父上下文,也导致所有作为ApplicationListeners的父上下文单例接收该事件?
我在文档中注意到[ContextClosedEvent]:(http://docs.spring.io/spring/docs/4.0.6.RELEASE/spring-framework-reference/htmlsingle/#context-functionality-events),“使用ConfigurableApplicationContext接口上的close()方法关闭ApplicationContext时发布。此处的“ Closed”表示所有单例bean都被销毁。上下文已到使用寿命;无法刷新或重新启动。”
从本质上讲,我要问的是事件发布仅限于特定的子上下文,还是在所有父/子上下文中传播?
最佳答案
将调用所有侦听器,但是参数(在本例中为ContextClosedEvent
)将指向要关闭的上下文。
以下测试创建一个父上下文,子上下文,启动它们,关闭父对象,然后关闭子对象。
public class ContextListenerTest {
@Test
public void contextListenerTest() {
AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(ParentContext.class);
AnnotationConfigApplicationContext child = new AnnotationConfigApplicationContext(ChildContext.class);
child.setParent(parent);
child.start();
System.out.println("closing child now...");
child.close();
System.out.println("closing parent now...");
parent.close();
}
public static class ParentContext {
@Bean
public ApplicationListener<ContextClosedEvent> closeEvent() {
return new ApplicationListener<ContextClosedEvent>() {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.println("parent listener: " + event);
}
};
}
}
public static class ChildContext {
@Bean
public ApplicationListener<ContextClosedEvent> closeEvent() {
return new ApplicationListener<ContextClosedEvent>() {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.println("child listener: " + event);
}
};
}
}
}
提供的测试将输出以下文本:
closing child now...
child listener: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3f1b7a14: startup date [Mon Jul 21 15:25:23 BRT 2014]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@94ac7e0]
parent listener: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@3f1b7a14: startup date [Mon Jul 21 15:25:23 BRT 2014]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@94ac7e0]
closing parent now...
parent listener: org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@94ac7e0: startup date [Mon Jul 21 15:25:22 BRT 2014]; root of context hierarchy]
在第一个关闭(子)中,两个侦听器均被执行。但是您可以获得使用
event.getApplicationContext()
关闭的上下文。