在什么情况下首选CommandLineRunner而不是在SpringBoot应用程序的main方法中编写其他代码。
我知道在main完成之前会执行CommandLineRunner。
答案 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}}类。
我有CommandLineRunner
,createDefaultUser()
等方法。
这样,我就不必依靠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 ====");
}
}