Spring Boot 的启动流程
1 - 先简单介绍一下run方法的过程
// 在spring boot中run方法才是启动应用的实际方法 最终返回的是一个ConfigurableApplicationContext容器 ConfigurableApplicationContext context = SpringApplication.run(SpringbootdemoApplication.class, args); // 在run方法中 创建了容器 并作了一系列的初始化处理 context = createApplicationContext(); // 创建一个容器对象 context.setApplicationStartup(this.applicationStartup);// 创建一个应用程序监视器 prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);// 准备上下文 refreshContext(context);// 刷新上下文 afterRefresh(context, applicationArguments);// 上下文刷新后
2 -- 首先是 createApplicationContext() 创建一个容器
// 通过调试可以看到最终返回的是 实现了它的 AnnotationConfigServletWebServerApplicationContext web容器 // 之所以是 AnnotationConfigServletWebServerApplicationContext 也是有选择的 在run方法创建应用容器的时候 根据应用类型来进行创建 switch (webApplicationType) {// 根据的应用程序的类型来进行选择的 webApplicationType case SERVLET: return new AnnotationConfigServletWebServerApplicationContext(); case REACTIVE: return new AnnotationConfigReactiveWebServerApplicationContext(); default: return new AnnotationConfigApplicationContext(); } // 首先进入的是 AnnotationConfigServletWebServerApplicationContext 的构造方法 public AnnotationConfigServletWebServerApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); // 首先创建了一个Bean定义阅读器 this.scanner = new ClassPathBeanDefinitionScanner(this);// 然后创建了一个Bean扫描器 }// 初次之外没做别的了
3 -- 其次是 refreshContext(context); 刷新上下文
// 可以看出来 refreshContext 实际上就是调用的容器的refresh方法 private void refreshContext(ConfigurableApplicationContext context) { if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } refresh(context); } protected void refresh(ConfigurableApplicationContext applicationContext) { applicationContext.refresh(); } // 而AnnotationConfigServletWebServerApplicationContext 中没有 refresh方法 // 所以实际上refreshContext调用的是ServletWebServerApplicationContext的refresh方法 // 而ServletWebServerApplicationContext也并没有refresh方法 public final void refresh() throws BeansException, IllegalStateException { try { super.refresh(); } catch (RuntimeException ex) { WebServer webServer = this.webServer; if (webServer != null) { webServer.stop(); } throw ex; } }// 最终调用的还是 老朋友 ApplicationContext 的refresh (refresh 方法就不同介绍了吧)
到此为止 run方法中需要着重介绍的东西也就没了
简单整理一下:其实spring boot的启动流程就是一个创建容器的过程
下面就是根据这个过程整理的一个简单的流程图: