SpringBoot——启动初始化数据
发布时间:2023-04-07 00:04:46 182
相关标签: # java# spring# springboot# 容器# 数据
前言
在我们用 springboot 搭建项目的时候,有时候会碰到在项目启动时初始化一些操作的需求 ,针对这种需求 spring boot为我们提供了以下几种方案供我们选择:
- ApplicationRunner 与 CommandLineRunner 接口
- Spring容器初始化时InitializingBean接口和@PostConstruct
- Spring的事件机制
ApplicationRunner与CommandLineRunner
我们可以实现 ApplicationRunner 或 CommandLineRunner 接口, 这两个接口工作方式相同,都只提供单一的run方法,该方法在SpringApplication.run(…)完成之前调用,我们先来看看这两个接口
@FunctionalInterface
public interface CommandLineRunner {
/**
* Callback used to run the bean.
* @param args incoming main method arguments
* @throws Exception on error
*/
void run(String... args) throws Exception;
}
@FunctionalInterface
public interface ApplicationRunner {
/**
* Callback used to run the bean.
* @param args incoming application arguments
* @throws Exception on error
*/
void run(ApplicationArguments args) throws Exception;
}
都只提供单一的run方法,接下来我们来看看具体的使用
ApplicationRunner
构造一个类实现ApplicationRunner接口
@Component
@Order(1)
public class ApplicationRunner1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("\u001B[32m[>>> startup ApplicationRunner1 <<<]");
}
}
很简单,首先要使用@Component将实现类加入到Spring容器中,如果有多个的话通过@Order(1)进行排序,然后实现其run方法实现自己的初始化数据逻辑就可以了
CommandLineRunner
对于这两个接口而言,我们可以通过Order注解或者使用Ordered接口来指定调用顺序, @Order() 中的值越小,优先级越高
@Component
@Order(1)
public class CommandLineRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("\u001B[32m[>>> startup runner1 <<<]");
}
}
同样需要加入到Spring容器中,CommandLineRunner的参数是最原始的参数,没有进行任何处理,ApplicationRunner的参数是ApplicationArguments,是对原始参数的进一步封装,如果有多个的话通过@Order(1)进行排序
ApplicationRunner和CommandLineRunner排序规则
- 通过Order指定顺序
- Order值相同ApplicationRunner的实现优先执行
源码分析
从SpringApplication.run方法的第8步callRunners开始
public ConfigurableApplicationContext run(String... args) {
```
// 第八步:执行Runners
callRunners(context, applicationArguments);
```
return context;
}
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
//获取容器中所有的ApplicationRunner的Bean实例
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
//获取容器中所有的CommandLineRunner的Bean实例
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
//对runners集合进行排序
AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) {
if (runner instanceof ApplicationRunner) {
//执行ApplicationRunner的run方法
callRunner((ApplicationRunner) runner, args);
}
if (runner instanceof CommandLineRunner) {
//执行CommandLineRunner的run方法
callRunner((CommandLineRunner) runner, args);
}
}
}
文章来源: https://blog.51cto.com/u_14014612/6007659
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报