简体   繁体   中英

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. If I use a different event such as ContextRefreshedEvent then it works just fine, but I need to hook into before it is created. 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 ).

This cascades down to your ApplicationContext normally via the AbstractApplicationContext on in Spring Boot case via the ConfigurableApplicationContext .

Example of working code below demonstrating how your callback would work (just explicitly call the start() method)

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.

If you drill down the SpringApplication#run() method you'll eventually see it .

Again here's a working example of how this would work using the 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.

For more details read this article from the Spring Blog . Just to quote the part about the 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.[..]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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