Tomcat组件及处理HTTP的请求过程与加载Spring容器

目录

Tomcat基础
Tomcat架构
Tomcat服务器配置
Web应用配置
Tomcat管理配置
Tomcat集群
Tomcat安全
Tomcat调优
Tomcat附件功能

Tomcat

Tomcat是一个免费的开源的(Servlet/JSP)web容器,它是Apache基金会的Jakarta项目中的一个核心项目,由Apache、Sun和其它一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和Jsp规范总能在Tomcat中得到体现。

与传统的桌面应用程序不同,Tomcat中的应用程序是一个WAR(WebArchive)文件。WAR是Sun提出的一种Web应用程序格式,与JAR类似,也是许多文件的一个压缩包。这个包中的文件按一定目录结构来组织:通常其根目录下包含有Html等文件的目录,另外还会有一个WEB-INF目录。通常在WEB-INF目录下有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的Servlet类和Jsp或Servlet所依赖的其它类(如JavaBean)。通常这些所依赖的类也可以打包成JAR放到WEB-INF下的lib目录下。
Tomcat不仅仅是一个Servlet容器,它也具有传统的Web服务器的功能:处理Html页面。但是与Apache相比,它的处理静态Html的能力就不如Apache。我们可以将Tomcat和Apache集成到一块,让Apache处理静态Html,而Tomcat处理Jsp和Servlet。这种集成只需要修改一下Apache和Tomcat的配置文件即可。

Tomcat 结构概览

在这里插入图片描述

Tomcat的两个核心组件:Connector和Container

1.Connector组件

Connector组件在8080端口上侦听客户请求,接收浏览器发过来的tcp连接请求,创建一个Request和一个Response对象分别用于和前端交换数据,然后会产生一个线程来处理这个请求并把产生的Request和Response对象传给Engine,从Engine中获得响应并返回给客户端。

Tomcat有两个经典的Connector,一个直接侦听来自浏览器的HTTP请求,另外一个侦听来自其他的WebServer的请求。Cotote HTTP/1.1 Connector在端口8080处侦听来自客户浏览器的HTTP请求,Coyote JK2 Connector在端口8009处侦听其他WebServer的Servlet/JSP请求。

Connector 最重要的功能就是接收连接请求然后分配线程让 Container来处理这个请求,所以这必然是多线程的,多线程的处理是 Connector设计的核心。

2.Container组件

Container是容器的父接口,该容器的设计用的是典型的责任链的设计模式,它由四个自容器组件构成,分别是Engine、Host、Context、Wrapper。这四个组件是负责关系,存在包含关系。

在这里插入图片描述

2.1 Engine

Engine 容器比较简单,它只定义了一些与Host 容器基本的关联关系。 Engine 没有父容器了,一个 Engine 代表一个完整的 Servlet 引擎。

2.2 Host

【Host】是 Engine 的子容器,一个 Host 在 Engine 中代表一个虚拟主机,这个虚拟主机的作用就是运行多个应用,它负责安装和展开这些应用,并且标识这个应用以便能够区分它们。它的子容器通常是 Context,它除了关联子容器外,还有就是保存一个主机应该有的信息。
Context定义在父容器 Host 中, Host 不是必须的,但是要运行 war 程序就必须要 Host,因为 war 中必有 web.xml 文件,这个文件的解析就需要 Host 了。

war部署过程
1、对于Host的appBase目录下所有符合条件的war包,由线程池完成部署。
2、创建StandardContext对象。
3、为Context实例添加ContextConfig生命周期监听器。
4、通过Host的addChild()方法将Context实例添加到Host。该方法会判断Host是否启动,如果已启动则直接启动Context对象。
5、将Context描述文件、War包及web.xml等资源添加到守护资源,以便文件发生变更时重新部署及加载Web应用。

2.3 Context

【Context】是 Servlet 运行的基本环境。它最重要的功能就是管理Servlet 实例,Servlet 实例在 Context 中是以 Wrapper 形式出现的,还有一点就是 Context 如何才能找到正确的 Servlet 来执行它呢?因为它获取子容器都是通过 request 来分配的。

一个ServletContext对象表示了一个Web应用程序的上下文。
运行在JAVA虚拟机中的每一个Web应用程序都有一个与之相关的Servlet上下文。ServletContext对象是Web服务器中的一个已知路径的根,Servlet上下文被定位于http://localhost:8080/项目名。以 /项目名+请求路径(称为上下文路径)开始的所有请求被发送到与此ServletContext关联的Web应用程序。

ServletContext 是一个全局的储存信息的空间,服务器开启其就存在,服务器关闭其才释放。
request,一个用户可有多个;session,一个用户一个;而servletContext,所有用户共用一个。

所以,为了节省空间提高效率,ServletContext中要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。比如把缓存信息存入Servlet上下文中,这样,每个用户只用从上下文中读入缓存信息就行了。

Tomcat缓存位置:/apache-tomcat-8.0.33/work/Catalina/localhost

2.4 Wrapper

Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。Wrapper 是最底层的容器没有子容器了。
Wrapper 的实现类是 StandardWrapper,StandardWrapper 还实现了拥有一个 Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper 将直接和 Servlet 的各种信息打交道。

说明:除了上述组件外,Tomcat中还有其他重要的组件,如安全组件security、logger日志组件、session、mbeans、naming等其他组件。这些组件共同为Connector和Container提供必要的服务。

Servlet

Servlet是一个小型的JAVA程序,运行在Web 服务器中来处理用户的请求,我们使用的Servlet都需要通过各种方式实现这个接口。
使用Servlet的话需要每个请求都去在web.xml中配置一个Servlet节点;
客户端发送请求,首先匹配web.xml中的路径,找到< url-pattern>值是login.action的sevlet,然后根据< servlet-name>去匹配< servlet- class>类,找到LoginServlet。

Servlet接口提供了5个方法:初始化init,销毁destory,处理请求service,获取Servlet参数getServletConfig,获取Servlet信息getServletInfo。主要的方法是前三个方法,体现了servlet的生命周期。

Tomcat 处理HTTP请求的过程

在这里插入图片描述
Tomcat Server处理一个HTTP请求的过程

1.用户在浏览器中输入网址localhost:8080/test/index.jsp,请求被发送到本机端口8080,被在那里监听的Coyote HTTP/1.1 Connector获得;
2.Connector把该请求交给它所在的Service的Engine(Container)来处理,并等待Engine的回应;
3.Engine获得请求localhost/test/index.jsp,匹配所有的虚拟主机Host;
4.Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机),名为localhost的Host获得请求/test/index.jsp,匹配它所拥有的所有Context。Host匹配到路径为/test的Context(如果匹配不到就把该请求交给路径名为“ ”的Context去处理);
5.path=“/test”的Context获得请求/index.jsp,在它的mapping table中寻找出对应的Servlet。Context匹配到URL Pattern为*.jsp的Servlet,对应于JspServlet类;
6.构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet()或doPost(),执行业务逻辑、数据存储等;
7.Context把执行完之后的HttpServletResponse对象返回给Host;Host返回给Engine;Engine返回Connector;Connector返回给客户Browser。

web.xml

Tomcat下Servlet的配置文件:web.xml
web.xml的作用是配置Http和Servlet之间的映射关系、filter、context参数等。这样通过这份约定的配置文件,Tomcat可以把Http请求映射到不同的Servlet实例上。所以在Servlet时代的web.xml中,会有很多项的配置。

Web容器初始化过程

在这里插入图片描述

Tomcat和Servlet的工作原理

1、启动一个WEB项目的时候, WEB容器会去读取它的配置文件web.xml, 读取< listener>和< context-param>两个结点。
2、容器创建一个ServletContext(servlet上下文), 这个web项目的所有部分都将共享这个上下文。
3、容器将< context-param>转换为键值对, 并交给servletContext。
4、容器创建< listener>中的类实例, 创建监听器。容器加载顺序是: listener -> filter -> servlet
在这里插入图片描述

一个Http的具体处理Servlet流程:

1.Web客户向Servlet容器(Tomcat)发出Http请求
2.Servlet容器分析客户的请求信息
3.Servlet容器创建一个HttpRequest对象,将客户请求的信息封装到这个对象中
4.Servlet容器创建一个HttpResponse对象
5.Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet对象。
6.HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息
7.HttpServlet调用HttpResponse对象的有关方法,生成响应数据
8.Servlet容器把HttpServlet的响应结果传给Web客户

Tomcat规定,所有的web应用,都放在它的webapps目录下,每个web应用对应该目录下的一个子目录。

尽管tomcat非常灵活而强大,可以作为web应用服务器,但是tomcat首先是一个Servlet容器,Servlet容器可以对Servlet进行管理,控制其生命周期。使其可以专注于自己应该做的事情,不需要考虑端口啊多线程啊socket之类的东西,也使得Servlet在各种环境下具有适应性。

Session

客户端发送请求,Tomcat(Servlet容器)会创建一个HttpSession对象,那么在HttpSession对象中,可以存放用户状态的信息,Servlet容器为HttpSession对象分配一个唯一标识符即Sessionid,Servlet容器把Sessionid作为一种Cookie保存在客户端的浏览器 中用户每次发出Http请求时,Servlet容器会从HttpServletRequest对象中取出Sessionid,然后根据这个Sessionid找到相应的HttpSession对象,从而获取用户的状态信息。

Session是存在于服务器端的,当把浏览器关闭时,浏览器并没有向服务器发送任何请求来关闭Session,Session也不会被销毁。之前的Session一直都在服务器端,而当我们关闭浏览器时,此时的Cookie是存在于浏览器的进程中的,当浏览器关闭时,Cookie也就不存在了。

	@RequestMapping("/getSession")
	public String aaa(HttpServletRequest req)
	{
		String session = req.getSession().getId();
		req.getSession().setMaxInactiveInterval(3);//设置Session3秒失效
		System.out.println("session= "+ session);
		return session;
	}
	
要使当前会话时间维持1小时,应设置 setMaxInactiveInterval()3600s
如果设置的值为零或负数,则表示会话将永远不会超时。常用于设置当前会话时间。

Tomcat容器加载Spring容器

Tomcat启动时会通过StandardContext.listenerStart() 初始化Spring的监听器,大致流程如下:

1.tomcat在启动web容器的时候会启动一个叫ServletContextListener的监听器

2.每当在web容器中有ServletContextListener这个接口被实例化的时候,web容器会通知ServletContextListener被实例的对象去执行其contextInitialized()的方法进行相应的业务处理,而spring框架在设计的过程中ContextLoadListener这个类实现了ServletContextListener这个接口,因此每当有ContextLoadListener这个类被实例化的时候,web容器会通知他执行contextInitialized()这个方法,然后执行initWebApplicationContext()方法,自动装配ApplicationContext的配置信息。

配置Spring

在tomcat容器启动后,会寻找项目中的web.xml文件,加载其中的信息,并创建一个ServletContext上下文对象,之后在web应用中可以获得其中的值。
先加载< context-param>节点,该节点加载的Spring配置文件,配置文件中是我们需要往Spring容器中注册的Bean对象配置。
有两种加载方式,如果在web.xml中不指定< context-param>,会默认去加载/WEB-INF/下的ApplicationContext.xml。

<!-- spring配置文件-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:resources/application.xml</param-value>
	</context-param>
  
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

加载完配置文件后,需要配置监听器< listener>。监听器的作用是监听ServletContext的对象是否创建。
ServletContextListener作为Servlet的监听者,会在ServletContext创建、销毁过程中监听ServletContextEvent事件,然后进行响应的处理。

web容器启动后,会创建ServletContext对象,加载监听器ContextLoaderListener,执行监听器的contextInitialized()方法,然后执行initWebApplicationContext()方法,自动装配ApplicationContext的配置信息。

配置Spring MVC

SpringMVC是Spring推出的基于Servlet标准的MVC框架实现。Spring MVC的入口是一个Servlet,也就是前置控制器DispatcherServlet,作为Spring MVC架构的核心,前置控制器能够拦截请求,将其分发给Controller处理。

DispatcherServlet实现了HttpServlet,那么SpringMVC在Tomcat看来,其实就是一个Servlet。所有的http请求都是映射到这个Servlet上,请求进入到DispatcherServlet之后,就进入到了框架之中了,由这个Servlet来统一的分配http请求到各个Controller。

<servlet>
	<servlet-name>DispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>DispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

Spring mvc和Servlet这两者的关系,就如同MyBatis和JDBC,一个性能好,一个开发效率高,一个是对另一个的封装。

总结

面试官问的这个问题:http请求发送到Tomcat是怎样完成一次请求的?
能回答说tomcat把请求分配给springmvc,具体业务逻辑由springmvc执行,听着有些含糊。
其实这个问题是把各自独立的内容整合在一起问而已,就把面试者难住了。
首先,我们来看看Tomcat、SpringMVC各自的定位和职责。

一句话总结

一个Tomcat的Server有2个核心组件Connector和Container。

【Connector】侦听8080端口接收来自web端的HTTP请求,然后分配线程来处理这个请求并把产生的Request和Response对象传给Container的Engine。

【Container】容器的设计模式是典型的责任链的设计模式,它由四个子容器组件构成,分别是Engine、Host、Context、Wrapper。

【Engine 】容器比较简单,它只定义了一些与Host 容器基本的关联关系。 Engine 没有父容器了,一个 Engine 代表一个完整的 Servlet 引擎。

【Host】虚拟主机的作用就是运行多个应用,它负责安装和展开这些应用,Host它的子容器通常是 Context。要运行 war 程序,就必须要 Host,因为 war 中有 web.xml 文件必需要解析。

【web.xml】的作用是配置Http和Servlet之间的映射关系。

【Context】是 Servlet运行的基本环境。一个ServletContext对象表示了一个Web应用程序的上下文。通过上下文路径将所有请求发送到与ServletContext关联的Web应用程序。

所以,为了节省空间提高效率,ServletContext中要放必须的、重要的、所有用户需要共享的线程又是安全的一些信息。比如把缓存信息存入Servlet上下文中。

【Servlet】是一个小型的JAVA程序;Servlet接口提供了5个方法:生命周期是初始化init,销毁destory,处理请求service;还有获取Servlet参数getServletConfig和获取Servlet信息方法getServletInfo。
添加Servlet需要每个都在web.xml中配置一个Servlet节点;
当客户端访问Servlet,首先匹配web.xml中的< url-pattern>路径值是login.action的sevlet,再根据< servlet-name>去匹配< servlet- class>类并找到LoginServlet。

【配置Spring】
tomcat容器启动加载顺序是: listener -> filter -> servlet。
在tomcat容器启动后,会寻找项目中的web.xml文件,加载其中的信息,并创建一个ServletContext上下文对象,之后在Web应用中可以获得其中的值。
如果在web.xml中不指定< context-param>,会默认去加载/WEB-INF/applicationContext.xml。

【SpringMVC】是Spring推出的基于Servlet标准的MVC框架实现。Spring MVC的入口是一个Servlet,也就是前置控制器DispatcherServlet,作为Spring MVC架构的核心,前置控制器能够拦截请求,将其分发给Controller处理。

【过滤器和拦截器】
(0)过滤器是J2EE标准,是在请求进入容器之后,还未进入Servlet之前进行预处理。而拦截器是被包裹在过滤器之中的,是进入Servlet之后执行的。
(1)Filter需要在web.xml中配置,依赖于容器;Interceptor在SpringMVC中配置,依赖于框架;
(2)拦截器是基于Java的反射机制,过滤器是基于函数回调。
(3)在Action生命周期中,过滤器只能在容器初始化时执行一次;而拦截器可以被多次调用。
(4)过滤器和拦截器的底层都是一样的,就是分了不同的功能实现,一个是拦截所有,一个是拦截具体的url;并且拦截器可以拦截静态资源。
(5)拦截器可以访问Action上下文,值栈里面的对象;过滤器不可以。
(6)拦截器可以获取IOC容器的各个bean,过滤器不行。

其他

Java程序员必须搞懂 Tomcat 这 8 大问题:

1.我们通常都知道Tomcat是一个Servlet容器,那么它到底是怎么实现Servlet规范的呢?
2.Tomcat到底是如何处理一个HTTP请求,并如何将请求传递给Servlet的呢?
3.Tomcat是怎么部署一个应用的?
4.Tomcat中War包和Jar包的区别是什么?
5.Tomcat和Socket、Tcp协议之间存在什么关系呢?到底什么是Socket?
6.Tomcat为什么要使用自定义类加载器?
7.Tomcat的架构设计非常复杂,存在很多组件,那么为什么要这么设计呢?
8.Tomcat到底该如何进行性能调优?


1.Tomcat的的缺省端口是多少,怎么修改?
2.tomcat有哪几种连接器运行模式(优化)?
3.Tomcat的有几种部署方式?
4.tomcat的容器是如何创建的servlet类实例?用到了什么原理?
5.tomcat如何优化?
6.内存调优
7.垃圾回收策略调优
8.共享会话处理
9.添加JMS远程监控
9.专业点的分析工具有
10.关于Tomcat的的会话数目
11.监视的Tomcat的内存使用情况
12.打印类的加载情况及对象的回收情况
13.Tomcat一个请求的完整过程

参考资料

Tomcat处理HTTP请求原理
https://www.cnblogs.com/small-boy/p/8042860.html

从tomcat到SpringMvc处理流程
https://blog.csdn.net/lsgqjh/article/details/55804165

Spring在web.xml中进行配置
https://www.cnblogs.com/yanqingguo/p/9856089.html

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值