Spring Boot 之 CommandLineRunner,ApplicationRunner

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

我们在开发过程中会有这样的场景:需要在容器启动的时候执行一些内容,比如:读取配置文件信息,数据库连接,删除临时文件,清除缓存信息,在Spring框架下是通过ApplicationListener监听器来实现的。在Spring Boot中给我们提供了两个接口来帮助我们实现这样的需求。这两个接口就是我们今天要讲的CommandLineRunner和ApplicationRunner,他们的执行时机为容器启动完成的时候。使用起来非常简单。只需要实现CommandLineRunner或者ApplicationRunner接口

for example:

    package com.batch.demo.service;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Component;

    /** * Created by WuTing on 2018/2/13. */
    @Component
    public class CommandExecute implements CommandLineRunner {
        private Logger LOG = LoggerFactory.getLogger(CommandExecute.class);

        @Autowired
        private ApplicationContext context;

        @Override
        public void run(String... strings) throws Exception {
            LOG.debug("CommandExecute run");
        }
    }

当项目启动成功后,就会执行run方法。那如果存在多个Runner又是如何执行的呢?
我们可以通过@Order或者实现Ordered来设置执行顺序。执行顺序是从小到大。

那到底runner是如何会在项目启动后执行的呢?我们可以通过程序入口跟踪代码找到。
1、找到程序入口,SpringApplication.run()
2、跟踪run方法直至找到SpringApplication的public ConfigurableApplicationContext run(String… args)方法,在该方法中我们可以看到调用了afterRefresh方法,afterRefresh方法就是对runner的调用。

    public ConfigurableApplicationContext run(String... args) {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            ConfigurableApplicationContext context = null;
            FailureAnalyzers analyzers = null;
            this.configureHeadlessProperty();
            SpringApplicationRunListeners listeners = this.getRunListeners(args);
            listeners.starting();

            try {
                ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
                Banner printedBanner = this.printBanner(environment);
                context = this.createApplicationContext();
                new FailureAnalyzers(context);
                this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
                this.refreshContext(context);
                this.afterRefresh(context, applicationArguments); //调用runner
                listeners.finished(context, (Throwable)null);
                stopWatch.stop();
                if (this.logStartupInfo) {
                    (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
                }

                return context;
            } catch (Throwable var9) {
                this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9);
                throw new IllegalStateException(var9);
            }
        }
     protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
            this.callRunners(context, args);
        }

        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);
            Iterator var4 = (new LinkedHashSet(runners)).iterator();

            while(var4.hasNext()) {
                Object runner = var4.next();
                if (runner instanceof ApplicationRunner) {
                    this.callRunner((ApplicationRunner)runner, args);  //调用runner
                }

                if (runner instanceof CommandLineRunner) {
                    this.callRunner((CommandLineRunner)runner, args);  //调用runner
                }
            }

        }

        private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
            try {
                runner.run(args);
            } catch (Exception var4) {
                throw new IllegalStateException("Failed to execute ApplicationRunner", var4);
            }
        }

        private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
            try {
                runner.run(args.getSourceArgs());
            } catch (Exception var4) {
                throw new IllegalStateException("Failed to execute CommandLineRunner", var4);
            }
        }

从源码可以看出, 会默认调用ApplicationRunner和CommandLineRunner类型的run方法。


来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring Boot 之 CommandLineRunner,ApplicationRunner

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏