SpringBoot源碼分析之CommandLineRunner、ApplicationRunner

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章