5

Could you describe different ways to run custom code before the application starts for data initialization or something else? (like ApplicationListener, CommandLineRunner etc.)

What is the difference between all of them? Which cases is better to use each of them in? I want to know not only one way to do that but an understanding when and what I need to use.

Here is enough old question with too many options to do that: Running code after Spring Boot starts

If it is a wrong place to ask this question, please, point me to the right one.

Daria Pydorenko
  • 1,754
  • 2
  • 18
  • 45

2 Answers2

5

What options I know:

  1. CommandLineRunner - receive command-line arguments as String

    @Slf4j
    @Component
    public class DemoCommandLineRunner implements CommandLineRunner {
    
        @Override
        public void run(String... args) {
            log.info("[CommandLineRunner] Args: " + Arrays.toString(args));
        }
    }
    
  2. ApplicationRunner - receive command-line arguments with names

    @Slf4j
    @Component
    public class DemoApplicationRunner implements ApplicationRunner {
    
        @Override
        public void run(ApplicationArguments args) {
            log.info("[ApplicationRunner] Args: ");
            nonOptionArgs(args);
            optionArgs(args);
        }
    
        private void nonOptionArgs(ApplicationArguments args) {
            args.getNonOptionArgs().forEach(log::info);
        }
    
        private void optionArgs(ApplicationArguments args) {
            args.getOptionNames().stream()
                    .map(args::getOptionValues)
                    .map(Objects::toString)
                    .forEach(log::info);
        }
    }
    
  3. ApplicationListener - listener for different events (for each event own class)

    @Slf4j
    @Component
    public class DemoApplicationListener implements ApplicationListener<ApplicationEvent> {
    
        @Override
        public void onApplicationEvent(ApplicationEvent event) {
            logEvent(event);
        }
    
        private void logEvent(ApplicationEvent event) {
            log.info("[DemoApplicationListener] Event: " + event);
        }
    }
    
  4. @EventListener - listener for different events (several events in one bean)

    @Slf4j
    @Component
    public class DemoEventApplicationListener {
    
        @EventListener
        public void handleContextRefreshedEvent(ContextRefreshedEvent event) {
            logEvent(event);
        }
    
        @EventListener
        public void handleApplicationReadyEvent(ApplicationReadyEvent event) {
            logEvent(event);
        }
    
        private void logEvent(ApplicationEvent event) {
            log.info("[DemoEventApplicationListener] Event: " + event);
        }
    }
    
  5. SmartLifecycle - configure bean lifecycle

    @Slf4j
    @Component
    public class DemoSmartLifecycle implements SmartLifecycle {
    
        private boolean isRunning;
    
        @Override
        public void start() {
            isRunning = true;
            log.info("[DemoSmartLifecycle]: Start");
        }
    
        @Override
        public void stop() {
            isRunning = false;
            log.info("[DemoSmartLifecycle]: Stop");
        }
    
        @Override
        public boolean isRunning() {
            return isRunning;
        }
    }
    
  6. SmartInitializingSingleton - triggered at the end of the singleton pre-instantiation phase

    @Slf4j
    @Component
    public class DemoSmartInitializingSingleton implements SmartInitializingSingleton {
    
        @Override
        public void afterSingletonsInstantiated() {
            log.info("[SmartInitializingSingleton] afterSingletonsInstantiated");
        }
    }
    

Github repo: https://github.com/venkaDaria/demo-bootstrap-spring

Daria Pydorenko
  • 1,754
  • 2
  • 18
  • 45
1

If you need to run some code "once the SpringApplication has started" you should use ApplicationRunner or CommandLineRunner - they work the same way.

ApplicationListener, or @EventListener with ApplicationReadyEvent do the same as well.

See my example.

The option you choose is up to you.

Cepr0
  • 28,144
  • 8
  • 75
  • 101
  • What about SmartLifecycle and other ways? So, does it depend only on my preferences? – Daria Pydorenko Jan 21 '19 at 09:35
  • @DariaPydorenko I didn't use it. But I think SmartLifecycle is a [bit more redundant option](http://selvakumaresra.herokuapp.com/spring-smartlifecycle-smart-shutdown-sequence-for-java-service/) than others if you need just run some code 'once the SpringApplication has started'. – Cepr0 Jan 21 '19 at 10:05