之前的博文介绍了tomcat有两大核心组件,connector和container,connector负责接受外部请求,container负责处理请求,本文从源码的角度介绍container的整体架构。
一、容器分类
tomcat容器为四个:
- Engine:代表容器引擎,管理多个虚拟站点,一个Service只有一个Engine
- Host:代表虚拟主机
- Context:代表一个web站点
- Wrapper:代表一个servlet
二、容器的结构
以上四大容器是父子关系,但是统一实现了Container接口:
public interface Container extends Lifecycle {
public Pipeline getPipeline();
public Container getParent();
public void setParent(Container container);
public void backgroundProcess();
public void addChild(Container child);
public Container findChild(String name);
public Container[] findChildren();
public void removeChild(Container child);
}
实现了统一接口,所以整体使用组合模式来进行组装和运转。
三、容器Pipeline、Valve(容器的执行链)
在Container的接口定义中有个Pippeline,这个就是当前容器的执行链,当执行到这个容器时,实际是执行这个pipeline进行实际的操作。
Pipeline接口定义
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);
}
Pipeline犹如一个链表,valve是其中的每一个节点(也是具体的执行单元),其中getFirst返回第一个节点,getBasic返回最后一个节点。
Valve定义
public interface Valve {
public Valve getNext();
public void setNext(Valve valve);
public void backgroundProcess();
public void invoke(Request request, Response response)
throws IOException, ServletException;
}
每一个Valve执行完毕后会调用getNext把请求传给下一个Valve。
BasicValve会调用子容器的getFirst节点把请求传给子容器。
上一篇博文中代码可以看到adapter是调用Engine的getFirst把请求传递到容器的。
整体过程
其中有一点需要说明的是BasicValve用于是pipeline的最后一个Valve。代码做了保证(setBasic方法)。
来源:oschina
链接:https://my.oschina.net/u/4285053/blog/4328258