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.[..]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With