tomcat 7 源码分析-13 处理request的Valve和Valve的链表Pipeline
tomcat打开endpoint的监听对通过某种协议,通常下是http的信息进行解析,组装成request,接着给Http11Protocol(ProtocolHandler)和Http11Processor处理。
- adapter.service(request, response);
adapter.service(request, response);
- connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
最终选择具体的Valve类处理request并生成response。
Valve和Pipeline的关系:Pipeline是valve的链表,表头是first,表尾是basic,具体的实现是StandardPipeline。
valve的实现是ValveBase及其子类。
先看ValveBase的定义
- public abstract class ValveBase extends LifecycleMBeanBase
- implements Contained, Valve {
- //------------------------------------------------------ Constructor
- public ValveBase() {
- this ( false );
- }
- public ValveBase( boolean asyncSupported) {
- this .asyncSupported = asyncSupported;
- }
- ........
- /**
- * The next Valve in the pipeline this Valve is a component of.
- */
- protected Valve next = null ;
public abstract class ValveBase extends LifecycleMBeanBase
implements Contained, Valve {
//------------------------------------------------------ Constructor
public ValveBase() {
this(false);
}
public ValveBase(boolean asyncSupported) {
this.asyncSupported = asyncSupported;
}
........
/**
* The next Valve in the pipeline this Valve is a component of.
*/
protected Valve next = null;
next就如同C和C++数据结构描述的指针,形如
- struct valve{
- valve * next
- };
struct valve{
valve * next
};
StandardPipeline的具体实现
- public class StandardPipeline extends LifecycleBase
- implements Pipeline, Contained {
- ...............................
- /**
- * The basic Valve (if any) associated with this Pipeline.
- */
- protected Valve basic = null ;
- /**
- * The first valve associated with this Pipeline.
- */
- protected Valve first = null ;
public class StandardPipeline extends LifecycleBase
implements Pipeline, Contained {
...............................
/**
* The basic Valve (if any) associated with this Pipeline.
*/
protected Valve basic = null;
/**
* The first valve associated with this Pipeline.
*/
protected Valve first = null;
StandardPipeline设置了两个哨兵,一个basic,一个是first。对链表的操作增加删除等,对哨兵有特殊处理的。
看个add的例子
- public void addValve(Valve valve) {
- // Validate that we can add this Valve
- if (valve instanceof Contained)
- ((Contained) valve).setContainer(this .container);
- // Start the new component if necessary
- if (getState().isAvailable()) {
- if (valve instanceof Lifecycle) {
- try {
- ((Lifecycle) valve).start();
- } catch (LifecycleException e) {
- log.error("StandardPipeline.addValve: start: " , e);
- }
- }
- }
- // Add this Valve to the set associated with this Pipeline
- if (first == null ) {
- first = valve;
- valve.setNext(basic);
- } else {
- Valve current = first;
- while (current != null ) {
- if (current.getNext() == basic) {
- current.setNext(valve);
- valve.setNext(basic);
- break ;
- }
- current = current.getNext();
- }
- container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve);
- }
public void addValve(Valve valve) {
// Validate that we can add this Valve
if (valve instanceof Contained)
((Contained) valve).setContainer(this.container);
// Start the new component if necessary
if (getState().isAvailable()) {
if (valve instanceof Lifecycle) {
try {
((Lifecycle) valve).start();
} catch (LifecycleException e) {
log.error("StandardPipeline.addValve: start: ", e);
}
}
}
// Add this Valve to the set associated with this Pipeline
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current != null) {
if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic);
break;
}
current = current.getNext();
}
}
container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve);
}
add一个元素是加在basic之前,处理pipeline的时候,是先取出first。
所以如果first==null,表面还没有pipeline种还没有元素,此时就先设置first。
不然,先找到basic以前的位置,将新的valve插入在basic之前,进行排队。
验证下可以看下面的remove操作
- public void removeValve(Valve valve) {
- Valve current;
- if (first == valve) {
- first = first.getNext();
- current = null ;
- } else {
- current = first;
- }
- while (current != null ) {
- if (current.getNext() == valve) {
- current.setNext(valve.getNext());
- break ;
- }
- current = current.getNext();
- }
- if (first == basic) first = null ;
- if (valve instanceof Contained)
- ((Contained) valve).setContainer(null );
- // Stop this valve if necessary
- if (getState().isAvailable()) {
- if (valve instanceof Lifecycle) {
- try {
- ((Lifecycle) valve).stop();
- } catch (LifecycleException e) {
- log.error("StandardPipeline.removeValve: stop: " , e);
- }
- }
- }
- try {
- ((Lifecycle) valve).destroy();
- } catch (LifecycleException e) {
- log.error("StandardPipeline.removeValve: destroy: " , e);
- }
- container.fireContainerEvent(Container.REMOVE_VALVE_EVENT, valve);
- }
public void removeValve(Valve valve) {
Valve current;
if(first == valve) {
first = first.getNext();
current = null;
} else {
current = first;
}
while (current != null) {
if (current.getNext() == valve) {
current.setNext(valve.getNext());
break;
}
current = current.getNext();
}
if (first == basic) first = null;
if (valve instanceof Contained)
((Contained) valve).setContainer(null);
// Stop this valve if necessary
if (getState().isAvailable()) {
if (valve instanceof Lifecycle) {
try {
((Lifecycle) valve).stop();
} catch (LifecycleException e) {
log.error("StandardPipeline.removeValve: stop: ", e);
}
}
}
try {
((Lifecycle) valve).destroy();
} catch (LifecycleException e) {
log.error("StandardPipeline.removeValve: destroy: ", e);
}
container.fireContainerEvent(Container.REMOVE_VALVE_EVENT, valve);
}