Springboot built-in Tomcat running flowchart and source code

insert image description here
insert image description here

Tomcat life cycle: create, initialize, run, stop, destroy

Call process
insert image description here
refresh, here is actually the core code of spring
insert image description here
Here
insert image description here
is the template method, see the subclass implements
insert image description here
insert image description here
insert image description here
insert image description here
AutoConfiguration, a ServletWebServerFactoryAutoConfiguration will be loaded in (details are in my SpringBoot automatic assembly),
insert image description here
insert image description here
insert image description here
so the factory corresponding to tomcat will be obtained.
Enter getWebServer(), there are multiple implementation
insert image description here
insert image description here
insert image description here
details of the creation
insert image description here
insert image description here
insert image description here
insert image description here

Create server stage (matryoshka)

  private void createWebServer() {
    
    
        //首次进来空的
        WebServer webServer = this.webServer;
        ServletContext servletContext = getServletContext();
        if (webServer == null && servletContext == null) {
    
    
            StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
            //获取tomcat对应工厂
            ServletWebServerFactory factory = getWebServerFactory();
            createWebServer.tag("factory", factory.getClass().toString());
            //工厂创建webServer
            this.webServer = factory.getWebServer(getSelfInitializer());
            createWebServer.end();
            getBeanFactory().registerSingleton("webServerGracefulShutdown",
                    new WebServerGracefulShutdownLifecycle(this.webServer));
            getBeanFactory().registerSingleton("webServerStartStop",
                    new WebServerStartStopLifecycle(this, this.webServer));
        }
        else if (servletContext != null) {
    
    
            try {
    
    
                getSelfInitializer().onStartup(servletContext);
            }
            catch (ServletException ex) {
    
    
                throw new ApplicationContextException("Cannot initialize servlet context", ex);
            }
        }
        initPropertySources();
    }



    /**
     * @Description:getWebServer
     * @Author: PABLO
     * @Date: 2022/5/16 22:34
     * @Params: [initializers]
     * @Return: org.springframework.boot.web.server.WebServer
     **/
    public WebServer getWebServer(ServletContextInitializer... initializers) {
    
    

        if (this.disableMBeanRegistry) {
    
    
            Registry.disableRegistry();
        }
        //创建Tomcat
        //Tomcat主要组件  server service connector container(engine host context wrapper servlet )
        Tomcat tomcat = new Tomcat();
        //创建本地临时目录 如C:\Users\29751\AppData\Local\Temp\tomcat.9000.4254207608449001881
        File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
        tomcat.setBaseDir(baseDir.getAbsolutePath());
        for (LifecycleListener listener : this.serverLifecycleListeners) {
    
    
            tomcat.getServer().addLifecycleListener(listener);
        }
        //创建Connector 默认协议HTTP1.1
        Connector connector = new Connector(this.protocol);
        connector.setThrowOnFailure(true);
        //往Server中的Service添加Connector,这里会创建server和service并绑定,而后在往service中添加connector
        tomcat.getService().addConnector(connector);
        //自定义tomcat参数
        //如extends TomcatEmbeddedServletContainerFactory后重写customizeConnector,设置超时时间、最大连接数等等
        //或使用ymal文件配置也可以自定义
        /*
        * # tomcat
            server:
              tomcat:
                # 最大线程数
                max-threads: 5
                # 最大连接数
                max-connections: 10
              port: 9090
        * */
        customizeConnector(connector);
        //tomcat设置Connector
        tomcat.setConnector(connector);
        //往HOST中设置自动部署标记值,getHost()中会创建engine,而后创建host,建立关联关系
        tomcat.getHost().setAutoDeploy(false);
        //设置pipeline的阀,处理请求会依次调用每个容器的每个阀,而后会继续调用下一个子容器...
        configureEngine(tomcat.getEngine());
        for (Connector additionalConnector : this.additionalTomcatConnectors) {
    
    
            tomcat.getService().addConnector(additionalConnector);
        }
        //给当前host创建一个context应用
        prepareContext(tomcat.getHost(), initializers);
        
        return getTomcatWebServer(tomcat);
    }


    protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
    
    
        /**
         * @Description: prepareContext
         * @Author: PABLO
         * @Date: 2022/5/16 23:07
         * @Params: [host, initializers]
         * @Return: void
         **/
        File documentRoot = getValidDocumentRoot();
        //创建容器,每个HOST中可以有多个context,每个context可以认为是一个应用,即我们的一个项目,webapp大家还记的吧
        TomcatEmbeddedContext context = new TomcatEmbeddedContext();
        if (documentRoot != null) {
    
    
            context.setResources(new TomcatServletWebServerFactory.LoaderHidingResourceRoot(context));
        }
        //设置初始值...
        context.setName(getContextPath());
        context.setDisplayName(getDisplayName());
        context.setPath(getContextPath());
        File docBase = (documentRoot != null) ? documentRoot : createTempDir("tomcat-docbase");
        context.setDocBase(docBase.getAbsolutePath());
        context.addLifecycleListener(new Tomcat.FixContextListener());
        context.setParentClassLoader((this.resourceLoader != null) ? this.resourceLoader.getClassLoader()
                : ClassUtils.getDefaultClassLoader());
        resetDefaultLocaleMapping(context);
        addLocaleMappings(context);
        try {
    
    
            context.setCreateUploadTargets(true);
        }
        catch (NoSuchMethodError ex) {
    
    
            // Tomcat is < 8.5.39. Continue.
        }
        configureTldPatterns(context);
        WebappLoader loader = new WebappLoader();
        loader.setLoaderClass(TomcatEmbeddedWebappClassLoader.class.getName());
        loader.setDelegate(true);
        context.setLoader(loader);
        if (isRegisterDefaultServlet()) {
    
    
            addDefaultServlet(context);
        }
        if (shouldRegisterJspServlet()) {
    
    
            addJspServlet(context);
            addJasperInitializer(context);
        }
        context.addLifecycleListener(new TomcatServletWebServerFactory.StaticResourceConfigurer(context));
        ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
        //将此context应用放入当前host
        host.addChild(context);
        //设置一些环境值
        configureContext(context, initializersToUse);
        //空实现,可扩展
        postProcessContext(context);
    }

Initialize the server stage (matryoshka)

 /**
     * @Description:容器启动核心代码
     * @Author: PABLO
     * @Date: 2022/5/17 13:04
     * @Params: []
     * @Return: void
     **/
    private void initialize() throws WebServerException {
    
    
        //控制台打印
        logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));
        synchronized (this.monitor) {
    
    
            addInstanceIdToEngineName();
            //获取应用this.tomcat.getHost().findChildren())
            Context context = findContext();
            //添加生命周期监听器
            context.addLifecycleListener((event) -> {
    
    
                if (context.equals(event.getSource()) && Lifecycle.START_EVENT.equals(event.getType())) {
    
    
                    // Remove service connectors so that protocol binding doesn't
                    // happen when the service is started.
                    removeServiceConnectors();
                }
            });
            //启动服务器并触发对应监听器
            //每个容器都有生命周期,从server开始依次启动
            this.tomcat.start();
        }
    }

    //server启动初始状态为NEW
    private volatile LifecycleState state = LifecycleState.NEW;
    /*
    * NEW(false, null), 新生状态
    INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),初始化中
    INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),初始化完毕
    STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),启动之前
    STARTING(true, Lifecycle.START_EVENT),启动中
    STARTED(true, Lifecycle.AFTER_START_EVENT),启动完成
    STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),停止之前
    STOPPING(false, Lifecycle.STOP_EVENT),正在停止
    STOPPED(false, Lifecycle.AFTER_STOP_EVENT),已经停止
    DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),正在销毁
    DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),已经销毁
    FAILED(false, null); 失败
    * */
    /**
     * @Description:容器启动核心代码
     * @Author: PABLO
     * @Date: 2022/5/17 13:04
     * @Params: []
     * @Return: void
     **/
    public final synchronized void start() {
    
    
        if (state.equals(LifecycleState.NEW)) {
    
    
            //套娃启动操作,每个容器都来一遍
            //最先是server-init,状态为new,进行初始化,状态为initializing,进行initInternal();
            //会调用server的initInternal()
            init();
        } else if (state.equals(LifecycleState.FAILED)) {
    
    
            stop();
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {
    
    
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }
    }
    /**
     * @Description: 初始化server的关键代码,server中初始化service
     * @Author: PABLO
     * @Date: 2022/5/17 13:12
     * @Params: []
     * @Return: void
     **/
    protected void initInternal() throws LifecycleException {
    
    
        // 初始化Service  核心代码,将service的new状态改为initializing,进行initInternal();
        for (Service service : services) {
    
    
            //会调用service的initInternal()
            service.init();
        }
    }
    /**
     * @Description: 初始化service的关键代码,如果engine为null,会先初始化engine
     * @Author: PABLO
     * @Date: 2022/5/17 13:15
     * @Params: []
     * @Return: void
     **/
    protected void initInternal() throws LifecycleException {
    
    
        //初始化engine,这时engine是空的,因为刚刚只初始化到了service
        if (engine != null) {
    
    
            //初始化engine,将new改为initializing,进行initInternal();和server和service不同的是,初始化后会将initializing状态改为initialized
            //调用engine的initInternal();
            engine.init();
        }

        //初始化映射器
        //web.xml中URL和servlet的映射关系,由该组件处理
        mapperListener.init();

        // 初始化engine后初始化连接器
        //而后初始化protocoHandler  endPoint逐层返回到server,整个容器初始化完毕..
        synchronized (connectorsLock) {
    
    
            for (Connector connector : connectors) {
    
    
                connector.init();
            }
        }
    }

Start service phase (matryoshka)

/**
 * @Description: 容器的初始化阶段和启动阶段
 * @Author: PABLO
 * @Date: 2022/5/17 13:59
 * @Params: []
 * @Return: void
 **/
public final synchronized void start() throws LifecycleException {
    
    
    //初始化阶段
    if (state.equals(LifecycleState.NEW)) {
    
    
        //套娃初始化
        init();
    } else if (state.equals(LifecycleState.FAILED)) {
    
    
        stop();
    } else if (!state.equals(LifecycleState.INITIALIZED) &&
            !state.equals(LifecycleState.STOPPED)) {
    
    
        invalidTransition(Lifecycle.BEFORE_START_EVENT);
    }

    //初始化阶段完毕,进入启动阶段
    setStateInternal(LifecycleState.STARTING_PREP, null, false);
    //套娃启动
    startInternal();
    if (state.equals(LifecycleState.FAILED)) {
    
    
        // This is a 'controlled' failure. The component put itself into the
        // FAILED state so call stop() to complete the clean-up.
        stop();
    } else if (!state.equals(LifecycleState.STARTING)) {
    
    
        // Shouldn't be necessary but acts as a check that sub-classes are
        // doing what they are supposed to.
        invalidTransition(Lifecycle.AFTER_START_EVENT);
    } else {
    
    
        setStateInternal(LifecycleState.STARTED, null, false);
    }
}

/**
 * @Description: 启动容器
 * @Author: PABLO
 * @Date: 2022/5/17 14:00
 * @Params: []
 * @Return: void
 **/
protected void startInternal() throws LifecycleException {
    
    
    //设置server状态为starting
    setState(LifecycleState.STARTING);
    //启动service、 engine
    synchronized (servicesLock) {
    
    
        for (Service service : services) {
    
    
            service.start();
        }
    }
}

Note: In onRefresh, tomcat is only created and initialized, but it is not started, and it is started in finishRefresh()–>startBeans()
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/GiantCrocodile/article/details/124810871