从未抛出ApplicationContext事件

Mar*_*ber 6 java spring

我试图ContextEventListener在所有ContextXXXEvent上为每个事件类型创建一个监听器,如下所示(这ContextRefreshedEvent是一个示例):

@Component
public class MyApplicationRefreshedListener implements ApplicationListener<ContextRefreshedEvent> {

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {
    logger.info(getClass(), "Event source [{}]", event.getSource());
  }

}
Run Code Online (Sandbox Code Playgroud)

无论ContextRefreshedEventContextClosedEvent被抓和他们的听众做了预期的工作.

我试图做同样的事情ContextStartedEvent,ContextClosedEvent但这两个事件听众都没有被捕获.

event.getSource(在刷新和关闭事件)印刷:

Event source [Root WebApplicationContext: startup date [Tue May 09 10:07:51 IDT 2017]; root of context hierarchy]
Run Code Online (Sandbox Code Playgroud)

(开始和停止)和(刷新和关闭)之间有什么区别吗?

是因为我的应用程序上下文是WebApplicationContext(作为event.getSource()节目吗?)

yas*_*nth 1

我已经浏览了 spring 代码。我将讨论 ContextStartedEvent。对于停止事件也可以给出类似的解释。

解释:

ContextStartedEvent 仅从start()AbstractApplicationContext 的方法发出,而不是从任何地方发出。由于您无法捕获 ContextStartedEvent,因此如果我们知道谁调用或不调用此方法,我们就可以找到答案。

在spring中,applicationContext可以通过两种方式启动。第一,我们显式调用此方法start(),它将触发上下文中 Bean 的初始化以及上下文初始化的其余部分。另一种方法是由 spring 负责上下文初始化。换句话说,我们不以这种方式处理上下文的启动停止。几乎我们所有人都在不知不觉中使用了第二种初始化方式。例如,您必须使用 xml 文件来加载使用ClassPathXmlApplicationContext的 bean 定义。这是从AbstractRefreshableApplicationContext继承的。

因此,我认为仅当您手动启动和停止(管理)ApplicationContext 时才会发出 ContextStartedEvent 和 ContextStoppedEvent 。还有另一组 ApplicationContext 实现,您可以使用它们来自行管理 ApplicationContext。我个人还没有尝试过。如果我成功地做到了这一点,我将更新答案。

对于 ContextStoppedEvent 也可以给出类似的解释。

更新:这与 spring 文档中提供的事件的定义一致(以及@coolgirl对此问题的其他答案)