zoukankan      html  css  js  c++  java
  • springboot中如何启动tomcat

    springboot启动时,会自动识别出当前环境是否是web环境还是非web环境。

    默认的web环境的context(DEFAULT_WEB_CONTEXT_CLASS):org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
    默认的非web环境的context(
    DEFAULT_CONTEXT_CLASS):org.springframework.context.annotation.AnnotationConfigApplicationContext

    以下代码为springboot启动类springApplication创建context代码:
    ConfigurableApplicationContext org.springframework.boot.SpringApplication.createApplicationContext():
    
    
        /**
         * Strategy method used to create the {@link ApplicationContext}. By default this
         * method will respect any explicitly set application context or application context
         * class before falling back to a suitable default.
         * @return the application context (not yet refreshed)
         * @see #setApplicationContextClass(Class)
         */
        protected ConfigurableApplicationContext createApplicationContext() {
            Class<?> contextClass = this.applicationContextClass;
            if (contextClass == null) {
                try {
                    switch (this.webApplicationType) {
                    case SERVLET:
                        contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS);
                        break;
                    case REACTIVE:
                        contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                        break;
                    default:
                        contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
                    }
                }
                catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Unable create a default ApplicationContext, "
                                    + "please specify an ApplicationContextClass",
                            ex);
                }
            }
            return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
        }

    那么我们来详细看下默认的web环境的AnnotationConfigServletWebServerApplicationContext的具体实现:

    public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry

    发现AnnotationConfigServletWebServerApplicationContext继承了org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext,

    我们看AnnotationConfigServletWebServerApplicationContext的代码,发现并没有和webServer(tomcat,jetty....)相关的代码。那么我们继续来看下父类ServletWebServerApplicationContext的实现:

    ServletWebServerApplicationContext:发现这个类是boot包下的,继承了GenericWebApplicationContext是spring-web这个jar包,推断springboot嵌入webServer的逻辑很有可能是在这个ServletWebServerApplicationContext

    类结构:public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext

    我们终于在org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext看到了和webServer相关的代码:

        @Override
        protected void onRefresh() {
            super.onRefresh();
            try {
                createWebServer();
            }
            catch (Throwable ex) {
                throw new ApplicationContextException("Unable to start web server", ex);
            }
        }
    @Override
        protected void finishRefresh() {
            super.finishRefresh();
            WebServer webServer = startWebServer();
            if (webServer != null) {
                publishEvent(new ServletWebServerInitializedEvent(webServer, this));
            }
        }

    其中onRefresh方法会在void org.springframework.context.support.AbstractApplicationContext.refresh() 中会在context注册BeanFactoryPostProcessor、执行BeanFactoryPostProcessor、注册BeanPostProcessor之后调用,

    finishRefresh方法会在void org.springframework.context.support.AbstractApplicationContext.finishRefresh()中会在context完成各种初始化(初始化bean)后被调用到,从而在context启动完成后,启动WebServer(tomcat、jetty)...

    接下来我们看下创建WebServer和启动WebServer的逻辑:

    private void createWebServer() {
            WebServer webServer = this.webServer;
            ServletContext servletContext = getServletContext();
            if (webServer == null && servletContext == null) {
                ServletWebServerFactory factory = getWebServerFactory();
                this.webServer = factory.getWebServer(getSelfInitializer());
            }
            else if (servletContext != null) {
                try {
                    getSelfInitializer().onStartup(servletContext);
                }
                catch (ServletException ex) {
                    throw new ApplicationContextException("Cannot initialize servlet context",
                            ex);
                }
            }
            initPropertySources();
        }
    private WebServer startWebServer() {
            WebServer webServer = this.webServer;
            if (webServer != null) {
                webServer.start();
            }
            return webServer;
        }
  • 相关阅读:
    Excel生成二维折线图详细教程 TheChosen
    sql语句截取字段中某一符号前几位的方法? TheChosen
    python快速下载包的镜像源? TheChosen
    Android 超大图长图浏览库 SubsamplingScaleImageView 源码解析
    记录线上APP一个排序比较引发的崩溃 Comparison method violates its general contract!
    Android 内存泄漏检测工具 LeakCanary(Kotlin版)的实现原理
    改数组长度
    枚举数组所有组合
    Ubuntu20.04启动后光标一直闪烁
    harbor镜像仓库清理操作
  • 原文地址:https://www.cnblogs.com/swave/p/11697668.html
Copyright © 2011-2022 走看看