spring-boot启动源码
1 运行SpringApplication.run()方法
--- org.springframework.boot.SpringApplication.SpringApplication(org.springframework.core.io.ResourceLoader, java.lang.Class<?>...)
2 确定应用程序类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
3 加载所有的初始化器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里
自定义初始化器:
a)实现 ApplicationContextInitializer接口 b)META-INF/spring.factories 配置文件
1 2 3 4 5 6 7 8 9 10 11 12 | import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; /** * 初始化器 */ public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { System. out .println( "我是初始化的 MyApplicationContextInitializer..." ); } } |
配置
1 2 | org.springframework.context.ApplicationContextInitializer=\ com.application.MyApplicationContextInitializer |
4、加载所有的监听器
配置在spring-boot-autoconfigure 和 spring-boot 的spring.factories里
监听器加载的是实现了ApplicationListener 接口的类
5 设置运行的主类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | --- org.springframework.boot.SpringApplication.run(java.lang.String...) public ConfigurableApplicationContext run(String... args) { //开启计时器 StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null ; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); //获取并启动监听器 SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try { //设置应用程序参数,main方法里面执行静态run方法传入的参数 ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); //准备环境变量,将maven和系统的环境变量都加载进来了 ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); //反射创建应用程序上下文 context = createApplicationContext(); //*实例化异常报告器。自定义异常报告器:继承 SpringBootExceptionReporter 接口 //*1 开启异常报警器 exceptionReporters = getSpringFactoriesInstances( SpringBootExceptionReporter. class , new Class[] { ConfigurableApplicationContext. class }, context); //*2 以下代码中发生异常都会执行异常报警器 //准备上下文环境,为下一步刷新作准备:postProcessApplicationContext、applyInitializers、registerSingleton prepareContext(context, environment, listeners, applicationArguments, printedBanner); //刷新上下文,属于spring范畴,自动装配和启动tomcat refreshContext(context); //后置处理,留给用户扩展使用 afterRefresh(context, applicationArguments); //结束计时器 stopWatch.stop(); if ( this .logStartupInfo) { new StartupInfoLogger( this .mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } //发布上下文准备就绪事件 listeners.started(context); //扩展功能,启动自定义的run方法 callRunners(context, applicationArguments); } catch (Throwable ex) { //3 捕获异常并调用异常报警器方法 handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null ); throw new IllegalStateException(ex); } return context; } |
* 自定义异常报告器
配置在spring.factories里
监听器加载的是实现了 SpringBootExceptionReporter 接口的类
自定义异常报告器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | import org.springframework.boot.SpringBootExceptionReporter; import org.springframework.context.ConfigurableApplicationContext; public class MyExceptionReporter implements SpringBootExceptionReporter { private ConfigurableApplicationContext context; // 必须要有一个有参的构造函数,否则启动会报错 MyExceptionReporter(ConfigurableApplicationContext context) { this .context = context; } @Override public boolean reportException(Throwable failure) { System. out .println( "进入异常报告器" ); failure.printStackTrace(); // 返回false会打印详细springboot错误信息,返回true则只打印异常信息 return false ; } } |
配置
1 2 | org.springframework.boot.SpringBootExceptionReporter=\ com.baoyun.iyb.config.application.MyExceptionReporter |
* 执行自定义的run方法
1。实现 ApplicationRunner 接口
2。实现 CommandLineRunner 接口
com.init.MyRunner
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.CommandLineRunner; public class MyRunner implements ApplicationRunner, CommandLineRunner { @Override public void run(ApplicationArguments args) throws Exception { System. out .println( " 我是自定义的run方法1,实现 ApplicationRunner 接口既可运行" ); } @Override public void run(String... args) throws Exception { System. out .println( " 我是自定义的run方法2,实现 CommandLineRunner 接口既可运行" ); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理