我是靠谱客的博主 激昂眼睛,最近开发中收集的这篇文章主要介绍CommandLineRunner 与 ApplicationRunner,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

功能

在容器启动之后,为了实现部分资源的预热,可以通过SpringBoot的扩展接口(CommandLineRunner 与 ApplicationRunner)来实现。

注意:执行时机为容器启动完成的时候

使用

  • 示例
@Component
public class WarmUpCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... var1) throws Exception {
long start = System.currentTimeMillis();
logger.info("开始资源预热");
// 预加载资源 ...
long end = System.currentTimeMillis();
logger.info("资源预热结束,cost(" + (end - start) + ")ms");
}
}
  • 排序
  • 实现 Ordered 接口
  • 使用 @Order 注解

按照Order的value值从小到大依次执行

  • 异常

实现该接口的方法内部如果抛异常的话,会直接导致应用启动失败,所以,一定要记得将危险的代码放在try-catch代码块里。

区别

  • 接收参数的类型不同:

ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。

  • 本质上没有差异:

接口参数本质都是应用启动参数,ApplicationRunner 将启动参数进行了封装,通过 ApplicationArguments 操作参数更加简便。

源码

SpringApplication.run方法
调用 callRunners

//
SpringApplication
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
// 启动参数封装
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
// 执行runner
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}

最后

以上就是激昂眼睛为你收集整理的CommandLineRunner 与 ApplicationRunner的全部内容,希望文章能够帮你解决CommandLineRunner 与 ApplicationRunner所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部