乌市泽哥 发表于 2024-8-30 19:44:19

四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如

四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat

@
目录

[*]四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如何关联 Spring 容器) 以及个人编写启动 Tomcat
[*]1. 源码分析 Spring Boot是如何启动 Tomcat ,并支持访问 @Controller 的 Debug 流程分析

[*]1.1 源码分析: SpringApplication.run( ) 方法

[*]2. 自己编写实现 Spring Boot 底层机制【Tomcat启动分析 + Spring容器初始化 + Tomcat如何关联 Spring容器】

[*]2.1 实现任务阶段1:创建Tomcat 并启动
[*]2.2 实现任务阶段2:创建Spring容器
[*]2.3 实现任务阶段3:将Tomcat 和 Spring 容器关联,并启动Spring容器

[*]3. 末了:

1. 源码分析 Spring Boot是如何启动 Tomcat ,并支持访问 @Controller 的 Debug 流程分析

进行源码分析,天然是少不了,Debug 的。下面就让我们打上断点 ,Debug起来吧
1.1 源码分析: SpringApplication.run( ) 方法

SpringApplication.run()
DeBugSpringApplication.run(MainApp.class, args); 看看 Spring Boot 是如何启动 Tomcat的 我们的Debug 目的:紧抓一条线,就是看到 tomcat 被启动的代码: 好比 tomcat.start()

[*]SpringApplication.java
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438104-1882276552.png
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437955-1890849399.png
// 这里我们开始 Debug SpringApplication。run()
   public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
      return run(new Class[]{primarySource}, args);
    }
[*]SpringApplication.java
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437847-376452826.png
    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
      return (new SpringApplication(primarySources)).run(args);
    }3.SpringApplication.java
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437872-1500967627.png
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438100-1086368272.png
public ConfigurableApplicationContext run(String... args) {
      StopWatch stopWatch = new StopWatch();
      stopWatch.start();
      DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
      ConfigurableApplicationContext context = null;
      this.configureHeadlessProperty();
      SpringApplicationRunListeners listeners = this.getRunListeners(args);
      listeners.starting(bootstrapContext, this.mainApplicationClass);

      try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();// 特别分析: 创建容器
            context.setApplicationStartup(this.applicationStartup);
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);// 特别分析:刷新应用程序上下文,比如:初始化默认设置/注入相关Bean/启动 tomcat
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
      } catch (Throwable var10) {
            this.handleRunFailure(context, var10, listeners);
            throw new IllegalStateException(var10);
      }

      try {
            listeners.running(context);
            return context;
      } catch (Throwable var9) {
            this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
      }
    }
[*]SpringApplication.java : 容器类型很多,会根据你的 this.webApplicationType 创建对应的容器
默认 this.webApplicationType 是 servlet 也就是 web 容器/处置惩罚的 servlet
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438113-1361501726.png
    protected ConfigurableApplicationContext createApplicationContext() {
      return this.applicationContextFactory.create(this.webApplicationType);
    }
[*]ApplicationContextFactory.java
默认是进入这个分支 case SERVLET:返回 new AnnotationConfigServletWebServerApplicationContext();
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438095-389499239.png
public interface ApplicationContextFactory {
    ApplicationContextFactory DEFAULT = (webApplicationType) -> {
      try {
            switch(webApplicationType) {
            case SERVLET:// 默认是进入这个分支
                return new AnnotationConfigServletWebServerApplicationContext();
            case REACTIVE:
                return new AnnotationConfigReactiveWebServerApplicationContext();
            default:
                return new AnnotationConfigApplicationContext();
            }
      } catch (Exception var2) {
            throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2);
      }
    };

    ConfigurableApplicationContext create(WebApplicationType webApplicationType);

    static ApplicationContextFactory ofContextClass(Class<? extends ConfigurableApplicationContext> contextClass) {
      return of(() -> {
            return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
      });
    }

    static ApplicationContextFactory of(Supplier<ConfigurableApplicationContext> supplier) {
      return (webApplicationType) -> {
            return (ConfigurableApplicationContext)supplier.get();
      };
    }
}2.1 实现任务阶段1:创建Tomcat 并启动

https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438057-343044663.png
    private void refreshContext(ConfigurableApplicationContext context) {
      if (this.registerShutdownHook) {
            shutdownHook.registerApplicationContext(context);
      }
      this.refresh(context);// 特别分析,真正执行相关任务
    }2.2 实现任务阶段2:创建Spring容器

bean 对象。
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437999-39660925.png
    protected void refresh(ConfigurableApplicationContext applicationContext) {
      applicationContext.refresh();
    }bean 对象对应的 config 配置类
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437924-1637689286.png
    public final void refresh() throws BeansException, IllegalStateException {
      try {
            super.refresh();// 特别分析这个方法
      } catch (RuntimeException var3) {
            WebServer webServer = this.webServer;
            if (webServer != null) {
                webServer.stop();
            }

            throw var3;
      }
    }controller 处置惩罚业务哀求的控制器
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438109-87290193.png
public void refresh() throws BeansException, IllegalStateException {
      synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();// 特别分析,当父类完成通用的工作后,再重新动态绑定机制回到
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                  this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                this.destroyBeans();
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }

      }
    }2.3 实现任务阶段3:将Tomcat 和 Spring 容器关联,并启动Spring容器

https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204438070-202087265.png
protected void onRefresh() {
      super.onRefresh();

      try {
            this.createWebServer();创建 webServer 可以理解成会创建指定 web服务器-tomcat
      } catch (Throwable var2) {
            throw new ApplicationContextException("Unable to start web server", var2);
      }
    }https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437947-1002081214.png
private void createWebServer() {
      WebServer webServer = this.webServer;
      ServletContext servletContext = this.getServletContext();
      if (webServer == null && servletContext == null) {
            StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
            ServletWebServerFactory factory = this.getWebServerFactory();
            createWebServer.tag("factory", factory.getClass().toString());
            this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer
()}); // 特别分析,使用 TomcatServletWebServerFactory 创建一个TomcatWEbServer
            createWebServer.end();
            this.getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer));
            this.getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer));
      } else if (servletContext != null) {
            try {
                this.getSelfInitializer().onStartup(servletContext);
            } catch (ServletException var5) {
                throw new ApplicationContextException("Cannot initialize servlet context", var5);
            }
      }

      this.initPropertySources();
    }3. 末了:

“在这个末了的篇章中,我要表达我对每一位读者的感激之情。你们的关注和复兴是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继承在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”
https://img2024.cnblogs.com/blog/3084824/202408/3084824-20240830204437973-1681370004.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 四,分析Spring Boot底层机制(Tomcat 启动分析+Spring容器初始化+Tomcat如