`
smartvessel
  • 浏览: 80686 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

tomcat 7 源码分析-13 处理request的Valve和Valve的链表Pipeline

阅读更多

tomcat打开endpoint的监听对通过某种协议,通常下是http的信息进行解析,组装成request,接着给Http11Protocol(ProtocolHandler)和Http11Processor处理。

adapter.service(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;

 next就如同C和C++数据结构描述的指针,形如

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;

 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);
    }

 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);
    }
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics