什么是啟動類加載器
就是SpringBoot啟動后,要立馬執行的程序,這時候就需要啟動類加載器完整這個要求。
啟動類加載器實踐
1、創建第一個啟動類加載器(方式1)
1)、創建啟動類加載器,實現CommandLineRunner接口
@Component public class FirstCommandlineRunner implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println("\u001B[32m >>> startup fist runner<<<"); } }
2)、啟動項目,輸出如下
2、多個類加載器,如何控制調用順序。
只需要增加Order注解即可
第一個啟動類加載器
@Component @Order(1) public class FirstCommandlineRunner implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println("\u001B[32m >>> startup fist runner<<<"); } }
第二個啟動類加載器
@Component @Order(2) public class SecondCommandlineRunner implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println("\u001B[32m >>> startup second runner<<<"); } }
然后啟動項目,輸出如下
2、創建類加載器,方式二
1)、創建FirstApplicationRunner 類,實現 ApplicationRunner接口,然后設置Order為1
@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<<<"); } }
2) 同理,創建SecondApplicationRunner 類,實現 ApplicationRunner接口,然后設置Order為2
@Component @Order(2) public class SecondApplicationRunner implements ApplicationRunner{ @Override public void run(ApplicationArguments args) throws Exception { System.out.println("\u001B[32m >>> startup second application runner<<<"); } }
3)啟動項目,查看輸出結果如下
3、啟動類加載器原理
進入run方法,啟動類加載器的入口是callRunners方法
進入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接口的類實例增加到runners列表中
將實現CommandLineRunner接口的類實例增加到runners列表中。
然后進行排序AnnotationAwareOrderComparator.sort(runners);
排序完畢后依次調用callRunner方法
callRunner方法實現如下。里面調用各自的run方法
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); } }