Spring 在应用程序启动之前运行自定义代码的不同方法

Spring 在应用程序启动之前运行自定义代码的不同方法,spring,spring-boot,Spring,Spring Boot,您能描述一下在应用程序启动进行数据初始化或其他操作之前运行自定义代码的不同方法吗? (如ApplicationListener,CommandLineRunner等) 它们之间有什么区别?在哪种情况下使用它们更好? 我不仅想知道这样做的一种方法,而且想知道我需要在什么时候使用什么 这是一个有太多选项的老问题: 如果问这个问题的地方不对,请给我指出正确的地方。如果你需要运行一些代码“一旦SpringApplication启动,你应该使用ApplicationRunner或CommandLineRu

您能描述一下在应用程序启动进行数据初始化或其他操作之前运行自定义代码的不同方法吗? (如
ApplicationListener
CommandLineRunner
等)

它们之间有什么区别?在哪种情况下使用它们更好? 我不仅想知道这样做的一种方法,而且想知道我需要在什么时候使用什么

这是一个有太多选项的老问题:


如果问这个问题的地方不对,请给我指出正确的地方。

如果你需要运行一些代码“一旦
SpringApplication
启动
,你应该使用
ApplicationRunner
CommandLineRunner
,它们都可以工作

ApplicationListener
,或带有
ApplicationReadyEvent
@EventListener
也可以执行相同的操作

看我的

您选择的选项由您决定。

我知道哪些选项:

  • CommandLineRunner-以字符串形式接收命令行参数

    @Slf4j
    @Component
    public class DemoCommandLineRunner implements CommandLineRunner {
    
        @Override
        public void run(String... args) {
            log.info("[CommandLineRunner] Args: " + Arrays.toString(args));
        }
    }
    
  • ApplicationRunner-接收具有名称的命令行参数

    @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);
        }
    }
    
  • ApplicationListener-不同事件的侦听器(针对每个事件自己的类)

  • SmartLifecycle-配置bean生命周期

    @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;
        }
    }
    
  • SmartInitializingSingleton-在单例预实例化阶段结束时触发

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

  • Github repo:

    SmartLifecycle和其他方式如何?那么,这仅仅取决于我的喜好吗?@DariaPydorenko我没有用它。但我认为,如果您只需要“在SpringApplication启动后”运行一些代码,那么SmartLifecycle比其他生命周期更具优势。
    @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;
        }
    }
    
    @Slf4j
    @Component
    public class DemoSmartInitializingSingleton implements SmartInitializingSingleton {
    
        @Override
        public void afterSingletonsInstantiated() {
            log.info("[SmartInitializingSingleton] afterSingletonsInstantiated");
        }
    }