zoukankan      html  css  js  c++  java
  • 使用CommandLineRunner和ApplicationRunner接口及其源码分析

    一 、使用实例

      1.1  CommandLineRunner接口

      使用CommandLineRunner接口类似于Main方法启动,可以接受一个字符串数组的命令行参数,以下为具体实现:

    @Component
    public class MyCommandLineRunner implements CommandLineRunner{
    
        @Override
        public void run(String... args) throws Exception{
            //假装有代码
        }
    }

      1.2 ApplicationRunner 接口

      此种方式与实现CommandLineRunner接口的区别就是他的参数是ApplicationArguments。

    @Order(value = 1)
    @Component
    public class MyApplicationRunner implements ApplicationRunner{
    
        @Override
        public void run(ApplicationArguments args) throws Exception{
            //假装有代码
        }
    }

    二、源码分析

      2.1 主程序启动

     public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }

      2.2  ConfigurableApplicationContext run(String... args)方法

      调用以下方法,完成容器的初始化和其他必要的操作之后,执行callRunners(context, applicationArguments)方法。

    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);
                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;
        }

     2.3 callRunners方法

    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());
          // 根据优先级进行排序,其中ApplicationRuner.class和CommandLineRunner.class混合在一起进行排序。 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); } } }
  • 相关阅读:
    C# 获取计算机相关信息
    C# 创建Windows服务demo
    C# 嵌入互操作类型
    使用开源框架Sqlsugar结合mysql开发一个小demo
    C# 实现最小化托盘功能
    面试-PA和XSYX面试小结
    0103-springmvc的基本流程
    0102-aop
    java并发编程-12个原子类
    ej3-0开端
  • 原文地址:https://www.cnblogs.com/mayang2465/p/14386347.html
Copyright © 2011-2022 走看看