SpringBoot基础-启动加载器

使用启动加载器

实现CommandLineRunner 接口

@Order(1)
@Component
public class FirstCommandlineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("=========FirstCommandlineRunner=============");
    }
}

实现ApplicationRunner 接口

@Order(1)
@Component
public class SecondApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("=========SecondApplicationRunner=============");
    }
}

两种实现方式比较

相同点

  • 调用点一样
    都是在callRunners中调用

  • 实现方法名一样
    都是通过实现接口来重写run方法

  • 通过Order来决定实现顺序

差异点

  • 执行优先级差异,第二种 > 第一种
  • run方法入参不一致
    CommandLineRunner 实现run传入String… args
    ApplicationRunner 实现run传入ApplicationArguments args

执行结果

在这里插入图片描述

有执行结果可以看出,两种实现方式的Order一样,但是第二种的执行顺序早于第一种执行顺序,为什么会是这样的执行顺序,继续往下看

原理解析

run()方法中调用:callRunners

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);
	for (Object runner : new LinkedHashSet<>(runners)) {
		if (runner instanceof ApplicationRunner) {
			callRunner((ApplicationRunner) runner, args);
		}
		if (runner instanceof CommandLineRunner) {
			callRunner((CommandLineRunner) runner, args);
		}
	}
}
  • 在方法中首先获得ApplicationRunner和CommandLineRunner接口的实现类,然后对runners进行排序,排序后遍历调用执行callRunner方法
  • List runners = new ArrayList<>(); 用的是object来装所有的Runner,在排序的时候对两种实现都采用Order注解排序,所以会对两种实现方式基于Order来排序
  • 上面的两种实现方式,由于Order值一样都是1,但是runners.addAll()是添加ApplicationRunner接口实现对象,runners是个有序集合,所以第二种的执行顺序早于第一种
private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
	try {
		(runner).run(args);
	}
	catch (Exception ex) {
		throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
	}
}

private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
	try {
		(runner).run(args.getSourceArgs());
	}
	catch (Exception ex) {
		throw new IllegalStateException("Failed to execute CommandLineRunner", ex);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值