什么是启动加载器
如果有一段代码,需要在SpringBoot框架启动后立即执行,就需要运用行一个启动加载器。
实现方式
两种实现方式
第一种实现CommandLineRunner重写run方法
@Component
@Order(1)
public class FirstCommandlineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("\u001B[32m >>> startup first runner<<<");
}
}
第二种实现ApplicationRunner重写run方法
@Component
@Order(1)
public class FirstApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("\u001B[32m >>> startup first application runner<<<");
}
}
Order排序 order值相同ApplicationRunner优先
启动加载器原理
启动加载器的启动,在SpringBoot容器启动过后(run方法中的最后一步)
callRunners(context, applicationArguments);
主要逻辑
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList<>();
// 获取所有ApplicationRunner的实现类
// 根据类型获取当前容器中的实例
// 有一个判断容器是否启动的参数 this.active
// 在SpringApplication的run方法中的refreshContext方法内的refresh方法中的prepareRefresh方法中设置
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
// 获取所有CommandLineRunner的实现类
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
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);
}
}
}
- 添加ApplicationRunner实现到runners
- 添加CommandLineRunner实现到runners集合
- 对runner集合排序
- 遍历runner集合依次调用实现类run方法
两种实现方式的差异
- 执行优先级不一样
- run方法入参不一样,实现ApplicationRunner是ApplicationArguments类型参数,实现CommandLineRunner是String变量参数
相同点:
- 调用点一样
- 实现方法名一样
计时器
主要对象
public class StopWatch {
// ID
private final String id;
// 是否保存执行过的任务
private boolean keepTaskList = true;
// 执行过的任务列表
private final List<TaskInfo> taskList = new LinkedList<>();
// 任务开始时间
private long startTimeMillis;
// 任务名称
@Nullable
private String currentTaskName;
// 最后执行任务名称
@Nullable
private TaskInfo lastTaskInfo;
// 任务总数
private int taskCount;
// 任务总耗时
private long totalTimeMillis;
}
- 构建StopWatch对象: StopWatch stopWatch = new StopWatch();
- 开始 stopWatch.start() 2.1 业务校验,当前是否有执行中的任务 2.2 保存任务名 2.3 记录当前系统时间
- 结束 stopWatch.stop() 3.1 业务校验,当前是否有执行中的任务 3.2 计算耗时 3.3 将当前任务添加到任务列表中 3.4 任务执行数加一 3.5 清空当前任务