【Tomcat】第四篇:Tomcat如何实现容器间协作

1.责任链模式

tomcat组件图

  1. 请求被Connector组件接收,创建Request和Response对象。
  2. Connector将Request和Response交给Container,先通过Engine的 pipeline组件流经内部的每个Valve。
  3. 请求流转到Host的pipeline组件中,并且经过内部Valve的过滤。
  4. 请求流转到Context的pipeline组件中,并且经过内部的Valve的过滤。
  5. 请求流转到Wrapper的pipeline组件中,并且经过内部的Valve的过滤。
  6. Wrapper内部的WrapperValve创建FilterChain实例,调用指定的 Servlet实例处理请求。
  7. 返回

2.pipeline valve机制

这整个层层递进的调用过程使用的是Pipeline-Value管道。

  • 责任链模式
  • 在请求处理过程中有很多处理者依次对请求进行处理,每个处理着负责做自己的相应的处理,然后一个个传递给下一个处理者

2.1 Valve

Valve:阀门,可以把它理解成请求拦截器,在 tomcat 接收到网络请求与触发 Servlet 之间执行;生产线(pipeline)可以配置阀门的位置。一个pipeline包含多个Valve,这些阀共分为两类

  • 基础阀(通过getBasic、setBasic方法调用)
    • StandardEngineValve:StandardEngine中的唯一阀门,主要用于从request中选择其host映射的Host容器StandardHost。
    • StandardHostValve:StandardHost中最后的阀门,主要用于从request中选择其context映射的Context容器StandardContext以及访问request中的Session以更新会话的最后访问时间。
    • StandardContextValve:StandardContext中的唯一阀门,主要作用是禁止任何对WEB-INF或META-INF目录下资源的重定向访问,对应用程序热部署功能的实现,从request中获得StandardWrapper
    • StandardWrapperValve:StandardWrapper中的唯一阀门,主要作用包括调用StandardWrapper的loadServlet方法生成Servlet实例和调用ApplicationFilterFactory生成Filter链。
  • 普通阀(通过addValve、removeValve调用)
    • AccessLogValve:记录请求日志,默认会开启
    • RemoteAddrValve:可以做访问控制,比如限制IP黑白名单
    • RemoteIpValve:主要用于处理 X-Forwarded-For 请求头,用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段
public interface Valve {
    
    
  // 类似链表结构
  public Valve getNext();
  public void setNext(Valve valve);
  // 重点,Request、Response分别是HttpServletRequest、HttpServletResponse的实现类
  public void invoke(Request request, Response response)
  // 是否支持异步
  public boolean isAsyncSupported();
}

2.2 Pipeline

Pipeline:管道,每个Container都包含一个Pipeline;接口标准实现:org.apache.catalina.core.StandardPipeline

  • 管道都是包含在容器中,所以有getContainer和setContainer方法。

  • Pipelin中维护了Valve的链表,整个调用链的执行是被valve来完成的,一个管道一般有一个基础阀(通过setBasic添加),可以有0到多个普通阀(通过addValve添加);valve完成自己的处理以后,就会调用getNext.invoke来触发下一个Valve调用

  • 不同的容器的pipeline之间的触发,上一层的最后一个valve负责调用下一层的第一个valve

  • Wrapper容器的最后一个Valve会创建一个Filter链,并调用doFilter方法,最终会调用Servlet的service方法。

    Valve和Filter

    • valve是tomcat的私有机制
    • Filter是在servlet级别的,是公有标准
    • valve工作在web容器级别,拦截所有应用的请求
    • Servlet Filter工作在应用级别,只能拦截某个Web应用的所有请求。
public interface Pipeline {
    
    
    public Valve getBasic();
    public void setBasic(Valve valve);
    public void addValve(Valve valve);
    public Valve[] getValves();
    public void removeValve(Valve valve);
    public Valve getFirst();
    public boolean isAsyncSupported();
    public Container getContainer();
    public void setContainer(Container container);
    public void findNonAsyncValves(Set<String> result);
}

文章的最后附一个参考链接

猜你喜欢

转载自blog.csdn.net/weixin_43935927/article/details/108640544