复制
ServletWebServerApplicationContext#onRefresh方法protected void onRefresh() {super.onRefresh();try {this.createWebServer();} catch (Throwable var2) {throw new ApplicationContextException("Unable to start web server", var2);}}
复制
ServletWebServerApplicationContext#createWebServer方法private void createWebServer() {WebServer webServer = this.webServer;ServletContext servletContext = this.getServletContext();if (webServer == null && servletContext == null) {ServletWebServerFactory factory = this.getWebServerFactory();this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});} else if (servletContext != null) {try {this.getSelfInitializer().onStartup(servletContext);} catch (ServletException var4) {throw new ApplicationContextException("Cannot initialize servlet context", var4);}}this.initPropertySources();}
复制
Spring容器启动后运行任务SpringApplication#callRunners方法private void callRunners(ApplicationContext context, ApplicationArguments args) {List<Object> runners = new ArrayList();// 通过应用上下文获取所有ApplicationRunner接口实现类的bean集合runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());// 通过应用上下文获取所有CommandLineRunner接口实现类的bean集合runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());AnnotationAwareOrderComparator.sort(runners);Iterator var4 = (new LinkedHashSet(runners)).iterator();// 遍历执行ApplicationRunner实现类和CommandLineRunner实现类中的run方法while(var4.hasNext()) {Object runner = var4.next();if (runner instanceof ApplicationRunner) {this.callRunner((ApplicationRunner)runner, args);}if (runner instanceof CommandLineRunner) {this.callRunner((CommandLineRunner)runner, args);}}private void callRunner(ApplicationRunner runner, ApplicationArguments args) {try {runner.run(args);} catch (Exception var4) {throw new IllegalStateException("Failed to execute ApplicationRunner", var4);}}private void callRunner(CommandLineRunner runner, ApplicationArguments args) {try {runner.run(args.getSourceArgs());} catch (Exception var4) {throw new IllegalStateException("Failed to execute CommandLineRunner", var4);}}
复制
处理启动异常最后我们来看看SprignBoot
应用程序启动发生异常时调用的方法
SpringApplication#handleRunFailure方法 private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception, Collection<SpringBootExceptionReporter> exceptionReporters, SpringApplicationRunListeners listeners) {try {try {// 处理程序退出编码this.handleExitCode(context, exception);if (listeners != null) {// 应用启动监听器发布启动失败事件listeners.failed(context, exception);}} finally {// 报告异常this.reportFailure(exceptionReporters, exception);if (context != null) {// 关闭Spring IOC容器context.close();}}} catch (Exception var9) {logger.warn("Unable to close ApplicationContext", var9);}// 调用反射工具类抛出运行时异常ReflectionUtils.rethrowRuntimeException(exception);}
复制
小结可以看到SpringBoot
项目启动过程的源码的源码还是非常复杂的 , 但是在难啃的骨头只要坚持下去还是能啃下它的 。通过分析SpringBoot
项目启动过程的源码分析 , 我们可以总结出SpringBoot
项目启动过程主要做了以下几件事情:
一、 实例化和初始化SpringApplication
对象实例 , 在这个过程会去初始化SpringApplication
对象的属性 , 包括:
- 1.设置是够注册关停钩子标识
- 2.推断Web应用程序类型
- 3.加载
META-INF/spring.factories
配置文件中配置的初始化器和启动监听器 - 4.推断项目主启动类等工作
SpringApplication
实例对象的run方法 , 该方法返回的是一个AnnotationConfig在这个过程中又可以分解为以下几个步骤
经验总结扩展阅读
- 一次SpringBoot版本升级,引发的血案
- 个人办理社保的流程是怎样的 个人怎么交社保
- 回门酒参加的都是谁 回门酒的流程
- 88vip双十一大额消费券领取流程2022 淘宝88vip双十一大额优惠券使用规则
- SpringBoot 03: 常用web组件 - - - 拦截器 + Servlet + 过滤器
- 房屋确权必须是户主吗 房屋确权的办理流程
- 公寓能不能抵押 房产证抵押贷款流程是什么
- SpringBoot 02: 初识SpringBoot
- 二手房网签注意事项 二手房网签流程
- 买房网签之后还有什么流程