springboot中tomcat的启动(一)入口

在springboot中,是融合了tomcat的启动与加载的,那么关于tomcat的启动与加载的入口就是研究的第一步,在EmbeddedWebApplicationContext类中,重写了AbstractApplicationContext的finishRefresh()方法,如下:

	protected void finishRefresh() {
		super.finishRefresh();
		EmbeddedServletContainer localContainer = startEmbeddedServletContainer();
		if (localContainer != null) {
			publishEvent(
					new EmbeddedServletContainerInitializedEvent(this, localContainer));
		}
	}
在finishRefresh方法中,第二行的startEmbeddedServletContainer()方法就是tomcat启动的入口,我们进入入口看下:
	private EmbeddedServletContainer startEmbeddedServletContainer() {
		EmbeddedServletContainer localContainer = this.embeddedServletContainer;
		if (localContainer != null) {
			localContainer.start();
		}
		return localContainer;
	}
在这个入口中,是通过embeddedServeletContainer类型的start()方法进入下一步的,这个embeddedServeletContainer类型是TomcatEmbeddedServletContainer,这个属性的赋值是在onrefresh方法中:
	protected void onRefresh() {
		super.onRefresh();
		try {
			createEmbeddedServletContainer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start embedded container",
					ex);
		}
	}
代码在start()方法中就进入了TomcatEmbeddedServletContainer的start()方法,关于TomcatEmbeddedServletContainer的类图如下:
EmbeddedServletContainer是tomcat中非常重要的一个类型,关于这个类型的示例,有一篇非常比错不错的文章,可供大家参考以及搞明白这个类型的作用:

深入SpringBoot:自定义EmbeddedServletContainer

在后面沿着代码进去,会调用了service.addConnector,此处用的是标准的service即是StandardService。在这个方法中调用了connector.start();方法,这个方法调用了父类LifecycleBase类的start()方法,关于LifecycleBase类是tomcat组件管理中非常重要的一个类型,负责组件的启动,停止等操作。然后在方法:startInternal();中调用回了Connector的startInternal()方法:

    @Override
    protected void startInternal() throws LifecycleException {

        // Validate settings before starting
        if (getPort() < 0) {
            throw new LifecycleException(sm.getString(
                    "coyoteConnector.invalidPort", Integer.valueOf(getPort())));
        }

        setState(LifecycleState.STARTING);

        try {
            protocolHandler.start();
        } catch (Exception e) {
            throw new LifecycleException(
                    sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
        }
    }
在这个方法中,最关键的一行代码就是protocolHandler.start();,这个方法中protocolHandler类型是:Http11NioProtocol,其类型定义在Connector的如下代码中:
    /**
     * Coyote Protocol handler class name.
     * Defaults to the Coyote HTTP/1.1 protocolHandler.
     */
    protected String protocolHandlerClassName =
        "org.apache.coyote.http11.Http11NioProtocol";
在此,普及一下tomcat类中的知识,在Connector中有一属性非常重要,就是protocol,这个属性决定了Connector用哪种方式与客户端连接,springboot1.5中默认使用的是Http11NioProtocol,而在protocol中也有一个非常重要的属性是endpoint,关于endpoint是接收非配socket的连接点了,至关重要, 这里有篇文章介绍了endpoint,非常好。在endpoint的start方法中做了端口接听,以及读写数据等等与客户端的交互工作。至此,在springboot的内置tomcat的入口就找到了。
最后再介绍一个tomcat相关的几个重要组件:
  • Server,默认是使用StandardServer,这个类是Lifecycle的子类,是tomcat启动的第一个组件。
  • Service,在Server属性中,tomcat紧接着Server启动的服务组件。
  • Engine,默认使用StandardEngine,一个engine表示为特定的服务请求处理流水线。由于服务可能有多个连接器,引擎会接收并处理来自这些连接器的所有请求,并将响应传递回适当的连接器以传输给客户端。该engine interface可以实现提供自定义的发动机,虽然这种情况并不常见。
  • Host,默认实现StandardHost,负责处理地址或者域名。

猜你喜欢

转载自blog.csdn.net/lz710117239/article/details/80191527