Servlet
Servlet是基于Java技术的Web组件,由容器托管,用于生成动态内容。与其它基于Java的组件技术一样,Servlet也基于平台无关的Java类格式,被编译为平台无关的字节码,可以被基于Java技术的web server动态加载并运行。客户端通过Servlet容器实现的请求/应答模型与Servlet交互。
Servlet容器是web server或application server的一部分,提供基于请求/响应发送模型的网络服务,解码基于MIME的请求,并格式化基于MIME的响应。Servlet容器也包含了管理Servlet生命周期。
典型事件序列如下:
- 客户端(如web浏览器)发送一个HTTP请求到web服务器
- Web服务器接收到请求并交给servlet容器处理,servlet容器可以运行在与宿主web服务器同一个进程中,也可以是同一主机的不同进程,或位于不同主机的web服务器中对请求进行处理。
- servlet容器根据servlet配置选择相应的servlet,并带上请求和响应参数调用它
- servlet执行业务逻辑,然后动态产生响应内容发送回客户端,发送数据到客户端是通过响应对象完成的
- 一旦servlet完成请求处理,servlet容器必须确保响应正确刷出,并将控制权还给宿主web服务器
Servlet生命周期
Servlet按照严格定义的生命周期被管理,该生命周期定义了Servlet如何被加载、实例化、初始化、处理客户端请求,以及何时结束服务。
- 加载和实例化
Servlet容器负责加载和实例化Servlet,加载和实例化可以发生在容器启动时,或延迟初始化直到有请求需要处理时。Servlet容器使用普通的Java类加载器加载Servlet类。可以从本地文件系统、远程文件系统或其它网络服务加载。
- 初始化
初始化的目的是使Servlet能读取持久化配置数据,初始化一些代价高的资源(如JDBC连接)或执行一些一次性动作。容器调用Servlet实例的init方法完成初始化。
- 请求处理
完成初始化后,Servlet就可以开始处理客户端请求了,Request和Response(HTTP场景下对应HttpServletRequest和HttpServletResponse)由容器通过参数传递到Servlet的service方法。
- 终止服务(End of service)
当Servlet容器确定servlet应该从服务中移除时,将调用Servlet接口的destory方法释放它使用的任何资源和保存任何持久化状态。容器调用destory方法之前,必须让正在执行的service方法执行完或者超过服务器定义的时间限制。destory方法完成后,容器释放servlet实例以便被垃圾回收。
Spring MVC
Spring-mvc支持Spring容器与MVC容器共存,Spring容器即根容器,mvc容器将根容器视为父容器。Spring容器以下列形式进行配置(web.xml).
1 | <listener> |
根据Servlet规范,组件加载顺序为listener->filter->servlet。如果spring根容器存在,它被保存在ServletContext中,key为WebApplicationContext.class.getName()+".ROOT"
。
Spring MVC处理请求流程:
- 客户端发送请求,容器将请求转发给DispatchServlet(web.xml中配置,DispatchServlet.initStrategies()中初始化)
- DispatchServlet根据请求信息调用Handlemapping,解析请求到对应的处理执行链(HandlerExecutionChain)
- 按照interceptor.preHandle() -> handler(由handlerAdapter适配器处理,适配器模式) -> interceptor.postHandle() 的顺序执行
- 完成执行链后,返回ModelAndView对象,Model是返回的数据对象,View是逻辑上的View
- ViewResolver根据逻辑View查找实际的View
- DispaterServlet把返回的Model传给View(视图渲染)
- 把View返回给客户端