SpringBoot CommandLineRunner

时间:2017-08-30 17:42:59

标签: java spring spring-boot

在什么情况下首选CommandLineRunner而不是在SpringBoot应用程序的main方法中编写其他代码。

我知道在main完成之前会执行CommandLineRunner。

8 个答案:

答案 0 :(得分:1)

我用它来解耦代码。 CommandLineRunner不是将一堆代码放入main方法,而是让您在代码库周围更均匀地分发它。这实际上取决于你传递的是什么样的标志以及为什么需要传递它们.Spring为你提供了很大的灵活性,让你以最简单的方式完成工作。

对于完整的命令行工具,您可以通过在init和核心行为之间划分代码来分离初始化和配置。

Spring Boot服务器可以根据从命令行传入的args覆盖配置。

答案 1 :(得分:1)

在简单的情况下,没有区别。

但是如果代码需要访问spring提供的功能,例如ioc或只有接口存储库/服务,则需要等待完整的应用程序启动。并且在完成之后调用超越的运行方法是有保障的。

此外,CommandLineRunner还有其他优点:

  • 可以多次实施
  • 在应用程序开始运行之前启动任何调度程序或记录任何消息的功能

答案 2 :(得分:0)

在启动应用程序后,我没有找到任何使用它而只是编写代码的充分理由 我唯一能想到的是在任何SpringApplicationRunListener调用#finished之前调用命令行运行程序。

我见过人们用它们来执行主应用程序逻辑,但我认为这是一个反模式 这样做的一个令人烦恼的事情是应用程序启动计时器仍在运行,当任务完成时,您将看到Started DemoApplication in 5.626 seconds (JVM running for 0.968)之类的日志条目。 看到关于你的应用程序的消息开始令人困惑,尽管实际上它已经完成了。

答案 3 :(得分:0)

我遇到了一个场景,在第一次从控制器端点命中方法之前,我必须保留加载到缓存中的数据库中的某些数据。在这种情况下,在扩展CommandLineRunner类之后,最好使用run方法点击填充缓存的方法,这样在应用程序启动之前,数据已经在缓存中可用。

答案 4 :(得分:0)

我会一直建议。它为您的“引导代码”增加了很多灵活性。

1)例如,命令行运行程序是spring @Beans,因此您可以在运行时将其激活/停用。

2)您可以通过添加@Order批注以有序方式使用它们

3)您可以像常规课程一样对它们进行单元测试

4)您可以将依赖项注入其中。然后,每个跑步者都可以拥有自己的依赖项。

如果在Spring Application类的main()方法中添加所有自举逻辑,那么上述所有内容将更加困难,即使不是不可能实现。

希望我的回答有帮助, 干杯

答案 5 :(得分:0)

我用它来填充我的默认数据。我通常会创建扩展ApplicationInitializer的{​​{1}}类。 我有CommandLineRunnercreateDefaultUser()等方法。 这样,我就不必依靠createDefaultSytemData()文件来为我填充数据库。 :)

答案 6 :(得分:0)

ApplicationRunner CommandLineRunner : 其中两个可以在应用程序启动完成之前执行一些自定义代码。

ComandLineRunner:

@Component
    public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);
    @Override
    public void run(String...args) throws Exception {
    logger.info(Arrays.toString(args));
    }
}

您可以直接获取args

ApplicationRunner

@Component
public class AppStartupRunner implements ApplicationRunner {
    private static final Logger logger = LoggerFactory.getLogger(AppStartupRunner.class);
    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.info(args.getOptionNames());
    }
}

ApplicationRunner有许多获取参数的方法 ComandLineRunner可以直接获取参数

如果您自定义两个跑步者类,则可以使用注释@Order来指定执行顺序

答案 7 :(得分:0)

public class Phone {

    @Autowired
    BeanExample beanExample;

    public void print(){
        beanExample.fn();
    }

}



           public class BeansCreatorClass {
    
          @Bean
          public  BeanExample getBeanExample(){
              return new BeanExample();
          }
    
    
          @Bean
        public Phone  getPhone(){
              return new Phone();
          }
    
    }
        
        
         @SpringBootApplication
            public class SpringBootRunnerConfigurationPropertiesApplication  implements CommandLineRunner, ApplicationRunner {
            
                
                public static void main(String[] args){
                    SpringApplication.run(SpringBootRunnerConfigurationPropertiesApplication.class, args);
                    System.out.println("==== spring boot commandLine is running === ");
            
                   // beans creator class is the class contains all beans needed 
                    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansCreatorClass.class);
            
                      Phone phone = applicationContext.getBean(Phone.class);
                      phone.print();
            
                      
            
                }
            
                // commandLineRunner
                public void run(String... args) throws Exception {
                    System.out.println("===  commandLine Runner is here  ==== ");
                }
            
            
                // application runner
                @Override
                public void run(ApplicationArguments args) throws Exception {
                    System.out.println("=== application runner is here ====");
                }
            }