我们在之前的文章中简单的说过SpringBoot的CommandLineRunner和ApplicationRunner这两个接口
SpringBoot之CommandLineRunner接口和ApplicationRunner接口,这篇文章中我们从源码上简单的分析一下这两个
接口。在org.springframework.boot.SpringApplication#run()这个方法中有这样一段代码:
afterRefresh(context, applicationArguments);
方法内容如下:
protected void afterRefresh(ConfigurableApplicationContext context,
ApplicationArguments args) {
callRunners(context, args);
}
SpringBoot的注释中说,在上下文刷新完之后调用这个方法。在调用这个方法的时候Spring容器已经启动完
成了。这里的context的真正对象是:AnnotationConfigEmbeddedWebApplicationContext,这个类贯
穿着SpringBoot的整个启动过程。我们看一下callRunners这个方法的内容:
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<Object>();
//从Spring容器中查找类型为ApplicationRunner的Bean
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
//从Spring容器中查找类型为CommandLineRunner的Bean
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
//将上一步得到的Bean进行排序
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<Object>(runners)) {
//如果是ApplicationRunner的实例
if (runner instanceof ApplicationRunner) {
callRunner((ApplicationRunner) runner, args);
}
//如果是CommandLineRunner的实例
if (runner instanceof CommandLineRunner) {
callRunner((CommandLineRunner) runner, args);
}
}
}
callRunner方法的内容就很简单了直接调用run方法。
private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
try {
(runner).run(args);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
}
}
ApplicationRunner和CommandLineRunner的区别就是run方法参数不同,ApplicationRunner中run方法
的参数是ApplicationArguments,CommandLineRunner中run方法的参数是String类型的可变参数。。