SpringBoot与TomCat、servlet关系(TomCat启动流程)二

上一篇文章我们介绍了TomCat启动流程并如何讲一个socket连接,一步步解析转化成servlet规范的request和Response的,这篇文章将继续介绍TomCat启动流程,如何将request根据URL转发到业务处理流程中的,以及,TomCat如何集成在springboot中。


从TomCat的架构可以看到主要分为连接器和容器两部分。连机器connector又分为EndPoint、processor、adapter三个组成。

  • EndPoint:主要负责网络通信,建立网络连接并检测IO事件

  • processor:主要负责应用层的协议解析(HTTP、AJP等)。

  • adapter:将processor处理完的内部的RequestResponse转换为标准的ServletRequest/ServletResponse

可以看出上一篇文章主要介绍了连接器connector的工作。

容器(container)中的四个部分的作用分别是:

  • Engine即为全局引擎容器,它的标准实现是StandardEngine。
  • Host在整个Servlet引擎中抽象出Host容器用于表示虚拟主机,它是根据URL地址中的主机部分抽象的,一个Servlet引擎可以包含若干个Host容器,而一个Host容器可以包含若干个Context容器。在Tomcat中Host的标准实现是StandardHost,它从虚拟主机级别对请求和响应进行处理。
  • Context对应一个Web应用程序,但Web项目的组成比较复杂,它包含很多组件。对于Web容器,需要将Web应用程序包含的组件转换成容器的组件。
  • Wrapper属于Tomcat中4个级别容器中最小级别的容器,与之相对应的是Servlet。

在调用的时候他们通过链式顺序调用,最终找到对应的servlet进行业务处理。

现在让我们从springboot启动开始一步步分析TomCat是如何启动的,并如何将springBoot中的URL业务处理方法注册入TomCat中的。

SpringApplication.run()方法是项目启动的地址,在创建context的时候会根据服务的类型创建对应的context



我们是servlet项目,所有创建AnnotationConfigServletWebServerApplicationContext实现对象,

SpringApplication.refreshContext(context)--->AbstractApplicationContext.refresh()--->ServletWebServerApplicationContext.createWebServer()

其中AbstractApplicationContextServletWebServerApplicationContext都是AnnotationConfigServletWebServerApplicationContext的父类

这里会发现factory的类型是TomcatServletWebServerFactory,spring中对于factory的实现还有其他几个如Jetty,Undertow,这里为啥是TomcatServletWebServerFactory类型呢,要想弄清这个,需要查看spring-boot-autoconfigure.jar下的/META-INF/spring.factories文件中的一个名为ServletWebServerFactoryAutoConfiguration的自动配置类



可以看到自动配置类会导入几个Embedded类,这些类在导入的时候,会判断依赖中是否有相关web服务器的类(@ConditionalOnClass注解),如果有则注入相关factory类。对于修改TomCat参数的TomcatWebServerFactoryCustomizer导入方式与上面类似。因为spring项目默认导入了TomCat的服务器,如果我们需要替换容器时需要将TomCat的依赖去除掉,具体参考这里,spring启动时提供了很多配置类,这些自动配置可以很好的协助程序员的工作。

继续回到createWebServer方法中,TomcatServletWebServerFactory.getWebServer()


这里将spring中的类信息传入到了Tomcat中很关键,这些参数是一系列实现了初始化接口的类,调用后这里实现了SpringBoot中写的Servlet三大组件(Servlet、Filter、Listener)传入到Tomcat中

prepareContext()--->configureContext()

这里的Context是org.apache.catalina下的,是TomcatStarter是javax.servlet.ServletContainerInitializer的实现类,是符合Servlet编程规范的,至此,spring将参数传入到了Tomcat中。

getTomcatWebServer(tomcat)--->创建TomcatWebServer()--->调用initialize()方法


这里会调用上面的实现了ServletContextInitializer接口的方法,实现注册Servlet、Filter、Listener这些部件。Tomcat也完成了启动。 Springboot中默认的Servlet是DispatcherServlet,对于URL和映射函数的保存可以参考这篇文章:spring boot中controller的URL存储匹配方式

具体的解析过程是在spring的bean注册的时候调用初始化方法进行解构保存。



pipeline会在Tomcat启动的时候创建,实现了链式调用。



当一个请求进来时,通过Tomcat的层层转发以及过滤器这些操作,最后进入到StandardWrapperValve中

ApplicationFilterChain调用完过滤器后,会去调用注册进来的Servlet方法去执行最终的业务代码。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容