上下文启动事件未在自定义侦听器中触发



我正在尝试使用这样的自定义应用程序侦听器连接到上下文的创建

@Component
public class ContextStartedListener implements ApplicationListener<ContextStartedEvent> {
@Override
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println("Context started"); // this never happens
}
}

onApplicationEvent方法永远不会触发。如果我使用不同的事件(例如ContextRefreshedEvent),那么它就可以正常工作,但我需要在创建它之前挂钩。有什么建议吗?谢谢!

[编辑]

编辑答案添加更多信息,因为投票反对。

您没有收到侦听器回调的原因是您没有显式调用生命周期start()方法 (JavaDoc)。

这通常通过AbstractApplicationContext在 Spring Boot 案例中通过ConfigurableApplicationContext级联到您的应用程序上下文

下面的工作代码示例演示了回调的工作原理(只需显式调用 start() 方法)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.stereotype.Component;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoApplication.class, args);
applicationContext.start();
}
@Component
class ContextStartedListener implements ApplicationListener<ContextStartedEvent> {
@Override
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println("Context started");
}
}
}

我之所以在ContextRefreshedEvent回调下方建议,是因为在幕后调用了refresh()代码。

如果向下钻取SpringApplication#run()方法,最终会看到它。

同样,这是一个如何使用ContextRefreshedEvent工作的工作示例:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Component
class ContextStartedListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("Context refreshed");
}
}
}

[编辑前]

将"泛型类型"更改为"ContextRefreshedEvent",然后它应该可以工作。

有关更多详细信息,请阅读春季博客中的这篇文章。只是引用有关ContextRefreshedEvent的部分:

[..]这允许 MyListener 在上下文刷新时收到通知,并且可以在应用程序时使用它来运行任意代码 上下文已完全启动。[..]

最新更新