责任链模式-Tomcat中Container处理请求方式
标准定义
使多个对象都有处理请求的机会,从而避免了请求的发送者和接收者之间的耦合关系。 将这些对象串成一条链,并沿着这条链一直传递该请求,直到有对象处理它为止。
使用方式
- 抽象出一个处理类父类,提取公有方法和属性。
abstract class Handler {
private Handler nextHandler;
/**
* 处理逻辑
*/
abstract void handler();
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public Handler getNextHandler() {
return nextHandler;
}
}
- 责任链模式中的处理类实现
class Handler1 extends Handler {
@Override
void handler() {
System.out.println("1");
if (this.getNextHandler() != null) {
this.getNextHandler().handler();
}
}
}
class Handler2 extends Handler {
@Override
void handler() {
System.out.println("2");
if (this.getNextHandler() != null) {
this.getNextHandler().handler();
}
}
}
- 测试
public class test {
public static Handler getHandlerChain() {
Handler1 handler1 = new Handler1();
Handler2 handler2 = new Handler2();
handler1.setNextHandler(handler2);
return handler1;
}
public static void main(String[] args) {
Handler handler = getHandlerChain();
handler.handler();
}
}
Tomcat中责任链模式使用
客户端请求通过Tomcat中connector封装后交给Container处理,而Container中处理请求的方式就是通过责任链模式。Container下有Engine、Host、Context、Wrapper四个子容器,这四个子容器通过pipline-valve形成链条依次执行。如下图:
-
Connector在接收到请求后会首先调用最顶层容器的Pipeline来处理,这里的最顶层容器的Pipeline就是EnginePipeline(Engine的管道);
-
在Engine的管道中依次会执行EngineValve1、EngineValve2等等,最后会执行StandardEngineValve,在StandardEngineValve中会调用Host管道,然后再依次执行Host的HostValve1、HostValve2等,最后在执行StandardHostValve,然后再依次调用Context的管道和Wrapper的管道,最后执行到StandardWrapperValve。
-
当执行到StandardWrapperValve的时候,会在StandardWrapperValve中创建FilterChain,并调用其doFilter方法来处理请求,这个FilterChain包含着我们配置的与请求相匹配的Filter和Servlet,其doFilter方法会依次调用所有的Filter的doFilter方法和Servlet的service方法,这样请求就得到了处理!
-
当所有的Pipeline-Valve都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给Connector了,Connector在通过Socket的方式将结果返回给客户端。
Pipeline-Valve使用的责任链模式和普通的责任链模式有些不同!区别主要有以下两点:
- 每个Pipeline都有特定的Valve,而且是在管道的最后一个执行,这个Valve叫做BaseValve,BaseValve是不可删除的;
- 在上层容器的管道的BaseValve中会调用下层容器的管道。
参考:Tomcat的原理及架构
上一篇: 设计模式之工厂模式