Home > Enterprise >  Run two ApplicationReadyEvents one after another after application startup
Run two ApplicationReadyEvents one after another after application startup

Time:05-08

I have two classes that implements ApplicationListener<ApplicationReadyEvent> as below. Since they both implement this interface they both run after startup but I would like to always run ClassB after ClassA is run. I don't have control to modify ClassA. I can only make changes to classB. How can I make sure the ClassB always run after ClassA.

public class ClassA implements ApplicationListener<ApplicationReadyEvent> {
    public void onApplicationEvent(ApplicationReadyEvent event){
        // do something
    }
}
public class ClassB implements ApplicationListener<ApplicationReadyEvent> {
    public void onApplicationEvent(ApplicationReadyEvent event){
        // do something
    }
}

Thanks in advance.

CodePudding user response:

Just out of the blue I would try it with annotating each listener with @Order. Spring normally orders injected lists this way. Could also be the case here.

CodePudding user response:

In case when you really don't have a possibility to control one of the listeners and enforce its order via an annotation or implementing the Ordered interface, I don't see any other option than to do it directly in the application context's listener registry after the context is fully loaded. (Although I'd really suggest arranging it so that you do have control of how and when the ClassA listener is registered.)

Here's what you can do to guarantee your ClassB listener is registered after the ClassA one:

  • make sure the ClassB listener you have control of is not a @Component, not declared as a @Bean and is not registered as a listener programmatically
  • create a separate listener for the ContextRefreshedEvent that registers your ClassB listener:
    @Component
    public class ContextRefreshedEventListener implements ApplicationListener<ContextRefreshedEvent> {
        public void onApplicationEvent(ContextRefreshedEvent event) {
            final ApplicationContext context = event.getApplicationContext();
            if (context instanceof ConfigurableApplicationContext) {
                final ConfigurableApplicationContext abstractApplicationContext = (AbstractApplicationContext) context;
                abstractApplicationContext.addApplicationListener(new ClassB());
            }
        }
    }
  • Related