什么是启动类加载器
就是SpringBoot启动后,要立马执行的程序,这时候就需要启动类加载器完整这个要求。
启动类加载器实践
1、创建第一个启动类加载器(方式1)
1)、创建启动类加载器,实现CommandLineRunner接口
1 2 3 4 5 6 7 | @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注解即可
第一个启动类加载器
1 2 3 4 5 6 7 8 | @Component @Order ( 1 ) public class FirstCommandlineRunner implements CommandLineRunner{ @Override public void run(String... args) throws Exception { System.out.println( "\u001B[32m >>> startup fist runner<<<" ); } } |
第二个启动类加载器
1 2 3 4 5 6 7 8 | @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
1 2 3 4 5 6 7 8 9 | @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
1 2 3 4 5 6 7 8 9 | @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方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); } } |
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2019-02-27 策略模式