springboot - Runner

ApplicationRunner and CommandLineRunner

开发中可能会遇到这样的需求,需要在容器启动的时候执行一些内容,比如读取配置文件,数据库操作等等。SpringBoot给我们提供了两个接口来帮助我们定制这种需求,这两个接口分别为CommandLineRunner和ApplicationRunner,他们会在容器启动完成后执行。这两个接口中有一个run方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。

public interface ApplicationRunner {
    void run(ApplicationArguments var1) throws Exception;
}

public interface CommandLineRunner {
    void run(String... var1) throws Exception;
}

1、 在SpringApplication的启动方法run中,完成上下文刷新后,会执行afterRefresh 方法

public ConfigurableApplicationContext run(String... args) {

        ...

        try {

            ...

            this.prepareContext(context, environment, listeners, ex, printedBanner);

            this.refreshContext(context);

            this.afterRefresh(context, ex);

            ...

            }

            return context;

        } catch (Throwable var9) {

           ...

        }
    }

2、 在afterRefresh方法中,会调用两种Runners,主要就是查找上下文中所有实现了ApplicationRunner 和 CommandLineRunner接口的bean,然后执行其run方法,这样我们就有机会定制自己的代码。

protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {
        this.callRunners(context, args);
    }

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
        ArrayList 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);
            }

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

    }

3、 分别实现ApplicationRunner 和 CommandLineRunner如下:

public class MyApplicationRunner implements ApplicationRunner {

    private final Logger logger = LoggerFactory.getLogger(MyApplicationRunner.class);

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {

        logger.info("MyApplicationRunner.run() is invoked! " + applicationArguments);
    }
}
public class MyCommandLineRunner implements CommandLineRunner {


    private final Logger logger  = LoggerFactory.getLogger(MyCommandLineRunner.class);

    @Override
    public void run(String... strings) throws Exception {

        logger.info("MyCommandLineRunner.run() is invoked! " + strings);

    }
}

4、将上述实现的类,配置为bean

@SpringBootApplication
public class Application {

    @Bean
    public MyCommandLineRunner startupRunner(){
        return new MyCommandLineRunner();
    }

    @Bean
    public MyApplicationRunner myApplicationRunner(){
        return new MyApplicationRunner();
    }

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
    }
}

5、执行main方法,可以看到输出如下内容:

...

2017-08-25 16:31:12.150  INFO 58583 --- [           main] c.s.boot.runner.MyApplicationRunner      : MyApplicationRunner.run() is invoked! org.springframework.boot.DefaultApplicationArguments@70925b45
2017-08-25 16:31:12.150  INFO 58583 --- [           main] c.s.boot.runner.MyCommandLineRunner      : MyCommandLineRunner.run() is invoked! [Ljava.lang.String;@1b9ea3e3
2017-08-25 16:31:12.152  INFO 58583 --- [           main] com.spring.boot.Application             : Started Application in 11.905 seconds (JVM running for 12.237)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值