首页 > 技术文章 > Tomcat为什么要使用Facde模式对Request对象进行包装?

yifanSJ 2018-07-30 13:04 原文

为了屏蔽内部catalina容器的相关方法,使用户免受非servlet标准方法的干扰。
tomcat中request的包装结构:
 
 

其中org.apache.coyote.Request是应用层拿到的Request对象的底层实现,不便使用,tomcat80/Request.java at trunk · apache/tomcat80 · GitHub
/**
 * This is a low-level, efficient representation of a server request. Most
 * fields are GC-free, expensive operations are delayed until the  user code
 * needs the information.
 *
 * Processing is delegated to modules, using a hook mechanism.
 *
 * This class is not intended for user code - it is used internally by tomcat
 * for processing the request in the most efficient way. Users ( servlets ) can
 * access the information using a facade, which provides the high-level view
 * of the request.
 *
 * Tomcat defines a number of attributes:
 * <ul>
 *   <li>"org.apache.tomcat.request" - allows access to the low-level
 *       request object in trusted applications
 * </ul>
 *
 * @author James Duncan Davidson [duncan@eng.sun.com]
 * @author James Todd [gonzo@eng.sun.com]
 * @author Jason Hunter [jch@eng.sun.com]
 * @author Harish Prabandham
 * @author Alex Cruikshank [alex@epitonic.com]
 * @author Hans Bergsten [hans@gefionsoftware.com]
 * @author Costin Manolache
 * @author Remy Maucherat
 */


org.apache.catalina.connector.Request类(tomcat80/Request.java at trunk · apache/tomcat80 · GitHub)封装了org.apache.coyote.Request类,实现了HttpServletRequest接口,已经具备了实际使用能力,不过它还包含了很多Catalina的方法,,这些方法不应该暴露给应用层,以免引起与其他容器实现的兼容性问题。

org.apache.catalina.connector.RequestFacade类(tomcat80/RequestFacade.java at trunk · apache/tomcat80 · GitHub)实现了HttpServletRequest接口,并在其中包含了一个org.apache.catalina.connector.Request对象,将所有HttpServletRequest接口的调用,都代理给org.apache.catalina.connector.Request对象来处理,这样就屏蔽了Catalina的相关的内部方法,使用户可以专注于servlet的标准方法。

从org.apache.catalina.connector.RequestFacade这个类,我们可以看到,这是一个使用了fa?ade模式的包装类,所以我们需要先了解一下fa?ade模式的相关知识。
Fa?ade模式介绍
facade模式的核心是为子系统的一组接口提供一个统一的界面,方便客户端使用子系统,客户端也不必关心子系统的具体实现。
facade设计模式的适用情况:
1. 原来的类提供的接口比较多,也比较复杂,而我们只需要使用其部分接口;
2. 原类提供的接口只能部分的满足我们的需要,且不希望重写一个新类来代替原类;
...
在本文中,RequestFacade是对Request的一个封装,由于Request本身提供的接口非常之多,而本系统中只需要使用其部分功能,在实际分析过程中,我们发现Request的具体工作最后delegate到底层的coyote.Request去做。

推荐阅读