简体   繁体   English

ContextStartedEvent未在自定义侦听器中触发

[英]ContextStartedEvent not firing in custom listener

I am trying to hook into the creation of the context using a custom application listener like this 我正在尝试使用这样的自定义应用程序侦听器来创建上下文

@Component
public class ContextStartedListener implements ApplicationListener<ContextStartedEvent> {

    @Override
    public void onApplicationEvent(ContextStartedEvent event) {
        System.out.println("Context started"); // this never happens
    }
}

But the onApplicationEvent method never fires. 但是onApplicationEvent方法永远不会触发。 If I use a different event such as ContextRefreshedEvent then it works just fine, but I need to hook into before it is created. 如果我使用诸如ContextRefreshedEvent类的其他事件,则它可以正常工作,但是在创建它之前,我需要先进行了解。 Any advice? 有什么建议吗? Thanks! 谢谢!

[Edit] [编辑]

Editing answer adding more info because of the downvote. 编辑表决由于投票不足而添加了更多信息。

The reason why you are not getting a callback by the listener is because you are not explicitly calling the LifeCycle start() method ( JavaDoc ). 之所以没有通过侦听器进行回调,是因为您没有显式调用LifeCycle start()方法( JavaDoc )。

This cascades down to your ApplicationContext normally via the AbstractApplicationContext on in Spring Boot case via the ConfigurableApplicationContext . 这通常在Spring Boot情况下通过ConfigurableApplicationContext通过AbstractApplicationContext层叠到您的ApplicationContext

Example of working code below demonstrating how your callback would work (just explicitly call the start() method) 下面的工作代码示例演示了回调的工作方式(只需显式调用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");
        }
    }
}

The reason why I suggested below the ContextRefreshedEvent callback instead is because behind the scenes the refresh() code is getting invoked. 我之所以在ContextRefreshedEvent回调下面建议的原因是,在后台调用了refresh()代码。

If you drill down the SpringApplication#run() method you'll eventually see it . 如果您深入研究SpringApplication#run()方法,最终将看到它

Again here's a working example of how this would work using the ContextRefreshedEvent : 再次这是一个使用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");
        }
    }
}

[Before Edit] [编辑前]

Change the Generic type to ContextRefreshedEvent instead and then it should work. 将通用类型改为ContextRefreshedEvent ,然后它应该可以工作。

For more details read this article from the Spring Blog . 有关更多详细信息,请阅读Spring Blog中的这篇文章 Just to quote the part about the ContextRefreshedEvent : 仅引用有关ContextRefreshedEvent的部分:

[..]This allows MyListener to be notified when the context has refreshed and one can use that to run arbitrary code when the application context has fully started.[..] [..]这使MyListener可以在上下文刷新时得到通知,并且可以在应用程序上下文完全启动时使用它来运行任意代码。[..]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM