我們在之前的文章中簡單的說過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類型的可變參數。。