聊透SpringMVC抬高视角和追本溯源
Posted Java3y
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊透SpringMVC抬高视角和追本溯源相关的知识,希望对你有一定的参考价值。
请看一个高层次的请求处理过程,如下图01:
第一步 :用户和Tomcat间建立连接并通过网络发送请求报文给Tomcat。
第二步 :Tomcat接收用户的报文然后解析报文,并用解析结果生成一个HttpServletRequest对象。
第三步 :Tomcat同时生成一个空的HttpServletResponse对象,并使用这两个对象去调用SpringMVC。
第四步 :SpringMVC从HttpServletRequest对象中获取参数,然后进行业务处理。
第五步 :SpringMVC把业务处理的结果放入HttpServletResponse中,处理流程回到Tomcat中。
第六步 :Tomcat把HttpServletResponse对象中的内容转化为报文并通过网络发回给用户。
第七步 :用户接收到报文并使用浏览器展示出来。
用户和Tomcat分别位于不同的地方,所有使用Socket交互。Tomcat和SpringMVC位于一个进程内,所以可以直接调用。
把SpringMVC看作一个整体, 和它密切相关的就是HttpServletRequest和HttpServletResponse两个对象,前者用于获取参数信息,后者用于存放处理结果。
抬高视角后,我们发现了SpringMVC的边界,SpringMVC只需要处理好界内事情即可,剩余的由Tomcat来负责。
那是因为它们都是Java Web规范下的产物。Java Web规范简单来说主要就是Servlet。Servlet这个词就是Server和Applet的结合体,意为运行在服务器上的小型程序。
Servlet本身是一个Java接口,不过我们通常把任何实现了这个接口的类也称作Servlet。Servlet有一个最大的特点就是它可以和指定的URL相关联。
当我们请求一个URL的时候,最终会来到和它关联的Servlet里面。所以Servlet是负责处理请求的地方,但是如何从URL来到Servlet里呢,这是Servlet管不了的。
负责这个事情的叫做Servlet容器。Servlet类就运行在Servlet容器中,容器负责接受请求,Servlet负责处理请求。这样的话所有环节就都通顺了。
因此Servlet容器就是Tomcat了,Servlet类就是SpringMVC了。所以说SpringMVC是基于Servlet构建起来的。这一切都是源于Servlet规范。
那是因为Servlet在它们之间定义了一座小桥,其实就是一个接口。这个接口由SpringMVC来实现,由Tomcat来调用这个实现。
请看这个接口,如下图02:
接口只有一个方法,方法的第一个参数是“感兴趣”的类的集合,哪些类才算是感兴趣的呢?又如何指定呢?继续往下看。
请看SpringMVC对该接口的实现类,如下图03:
在类的上面通过 @HandlesTypes 注解指定的类就是感兴趣的类。这里指定的是一个叫做 WebApplicationInitializer (web应用初始化器)的接口,那它的所有实现类就是感兴趣的类。
那Tomcat如何知道有这么一个实现类存在呢?因为Servlet又给出了规范,哈哈,规范走天下啊。规范规定:
在war包里的META-INF/services目录下,必须有个名为javax.servlet.ServletContainerInitializer的文件,文件内容必须是一个实现了该接口的类的全名。且这个实现类上可以使用@HandlesTypes注解,来指定你感兴趣的类。
这样Tomcat只要从每个war包里读出这个实现类的全名,然后就可以使用反射实例化它,接着调用它的onStartup方法就行了。
这样Tomcat的启动流程通过这座小桥就来到了SpringMVC里,然后带动了SpringMVC的启动,启动成功后就可以对外提供服务了。
肯定是不会的,因为有一个叫做ContextPath(上下文路径)的东西存在,它就相当于应用的名字,来把它们分开,同时它也是URL的一部分,所以不同应用的URL也是不可能一样的。
同时,Tomcat还定义了类加载器,使一个应用不会加载到别的应用的类,这样保证了安全性。也就是说,即使两个应用中都定义了完全一样的类,那也不是同一个类。
一个Tomcat运行多个应用,如下图04:
Tomcat既然要调用Servlet,那我们必须先把Servlet注册到Tomcat里才行。Tomcat会为每个应用创建一个上下文,称为Servlet上下文(ServletContext)。
每个应用都运行在自己的这个上下文中。如下图05:
一个应用主要就是一些Servlet和Filter,所以只需把这些Servlet和Filter注册到这个ServletContext里就可以了。
传统上,Servlet和Filter的配置信息都会放在应用的web.xml文件中,所以Tomcat在启动时会去读这个文件内容,自动进行相关注册。
所以应用信息、上下文路径、Servlet信息和它对应的URL信息都会存储在已启动好的Tomcat内部,这样当一个请求过来后,根据请求的URL信息就匹配出适合的Servlet,然后Tomcat就会去调用它。
以上是关于聊透SpringMVC抬高视角和追本溯源的主要内容,如果未能解决你的问题,请参考以下文章