springboot项目启动成功后执行一段代码的两种方式 - 醉东风 - 博客园

springboot项目启动成功后执行一段代码的两种方式

实现ApplicationRunner接口

复制代码; "复制代码")

package com.lnjecit.lifecycle; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * @author lnj
* createTime 2018-11-07 22:37
**/ @Component public class ApplicationRunnerImpl implements ApplicationRunner {

@Override public void run(ApplicationArguments args) throws Exception {
    System.out.println("通过实现ApplicationRunner接口,在spring boot项目启动后打印参数");
    String\[\] sourceArgs = args.getSourceArgs(); for (String arg : sourceArgs) {
        System.out.print(arg \+ " ");
    }
    System.out.println();
}

}

复制代码; "复制代码")

项目启动后,会打印如下信息:

实现CommandLineRunner接口

复制代码; "复制代码")

package com.lnjecit.lifecycle; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; /** * @author lnj
* createTime 2018-11-07 22:25
**/ @Component public class CommandLineRunnerImpl implements CommandLineRunner {

@Override public void run(String... args) throws Exception {
    System.out.println("通过实现CommandLineRunner接口,在spring boot项目启动后打印参数"); for (String arg : args) {
        System.out.print(arg \+ " ");
    }
    System.out.println();
}

}

复制代码; "复制代码")

 

 两种实现方式的不同之处在于run方法中接收的参数类型不一样

指定执行顺序

当项目中同时实现了ApplicationRunner和CommondLineRunner接口时,可使用Order注解或实现Ordered接口来指定执行顺序,值越小越先执行

原理

通过调试可以发现都是在 org.springframework.boot.SpringApplication#run(java.lang.String...)方法内的afterRefresh(上下文刷新后处理)方法时,会执行callRunners方法。

afterRefresh方法具体实现如下: 

protected void afterRefresh(ConfigurableApplicationContext context,

    ApplicationArguments args) {
callRunners(context, args);

}

callRunners方法具体实现如下: 

复制代码; "复制代码")

private void callRunners(ApplicationContext context, ApplicationArguments args) {

List<Object> runners = new ArrayList<Object>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners); for (Object runner : new LinkedHashSet<Object>(runners)) { if (runner instanceof ApplicationRunner) {
        callRunner((ApplicationRunner) runner, args);
    } if (runner instanceof CommandLineRunner) {
        callRunner((CommandLineRunner) runner, args);
    }
}

}

复制代码; "复制代码")

 可以看出上下文完成刷新后,依次调用注册的runners, runners的类型为 ApplicationRunner 或 CommandLineRunner

案例地址

https://github.com/linj6/springboot-learn/tree/master/springboot-runner

参考资料

https://blog.csdn.net/zknxx/article/details/52196427


Original url: Access
Created at: 2019-12-12 18:10:12
Category: default
Tags: none

请先后发表评论
  • 最新评论
  • 总共0条评论