zoukankan      html  css  js  c++  java
  • tomcat 的 Pipeline 机制

    一。server.xml

    在每个容器对象里面都有一个pipeline,Pipeline就像是每个容器的逻辑总线。

        <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true"
                xmlValidation="false" xmlNamespaceAware="false">
    
            <!-- SingleSignOn valve, share authentication between web applications
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
            -->
    
            <!-- Access log processes all example.
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"  
                   prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
            -->
    
          </Host>

    二。源码追踪

    1.Engine

        /**
         * Create a new StandardEngine component with the default basic Valve.
         */
        public StandardEngine() {
    
            super();
            pipeline.setBasic(new StandardEngineValve());
            /* Set the jmvRoute using the system property jvmRoute */
            try {
                setJvmRoute(System.getProperty("jvmRoute"));
            } catch(Exception ex) {
            }
            // By default, the engine will hold the reloading thread
            backgroundProcessorDelay = 10;
    
        }

    2.Host

        /**
         * Create a new StandardHost component with the default basic Valve.
         */
        public StandardHost() {
    
            super();
            pipeline.setBasic(new StandardHostValve());
    
        }

    3.Context

        /**
         * Create a new StandardContext component with the default basic Valve.
         */
        public StandardContext() {
    
            super();
            pipeline.setBasic(new StandardContextValve());
            broadcaster = new NotificationBroadcasterSupport();
    
        }

    4.Wrapper

        /**
         * Create a new StandardWrapper component with the default basic Valve.
         */
        public StandardWrapper() {
    
            super();
            swValve=new StandardWrapperValve();
            pipeline.setBasic(swValve);
            broadcaster = new NotificationBroadcasterSupport();
    
            if (restrictedServlets == null) {
                restrictedServlets = new Properties();
                try {
                    InputStream is = 
                        this.getClass().getClassLoader().getResourceAsStream
                            ("org/apache/catalina/core/RestrictedServlets.properties");
                    if (is != null) {
                        restrictedServlets.load(is);
                    } else {
                        log.error(sm.getString("standardWrapper.restrictedServletsResource"));
                    }
                } catch (IOException e) {
                    log.error(sm.getString("standardWrapper.restrictedServletsResource"), e);
                }
            }
            
        }

    三。ContainerBase

    把Pipeline接口的实现委托给成员变量pipeline

    public abstract class ContainerBase
        implements Container, Lifecycle, Pipeline, MBeanRegistration, Serializable {

    1.setBasic

        public void setBasic(Valve valve) {
    
            pipeline.setBasic(valve);
    
        }

    2.invoke

        public void invoke(Request request, Response response)
            throws IOException, ServletException {
    
            pipeline.getFirst().invoke(request, response);
    
        }

    3.继承

    四。StandardPipeline

    1.setBasic

        public void setBasic(Valve valve) {
    
            // Change components if necessary
            Valve oldBasic = this.basic;
            if (oldBasic == valve)
                return;
    
            // Stop the old component if necessary
            if (oldBasic != null) {
                if (started && (oldBasic instanceof Lifecycle)) {
                    try {
                        ((Lifecycle) oldBasic).stop();
                    } catch (LifecycleException e) {
                        log.error("StandardPipeline.setBasic: stop", e);
                    }
                }
                if (oldBasic instanceof Contained) {
                    try {
                        ((Contained) oldBasic).setContainer(null);
                    } catch (Throwable t) {
                        ;
                    }
                }
            }
    
            // Start the new component if necessary
            if (valve == null)
                return;
            if (valve instanceof Contained) {
                ((Contained) valve).setContainer(this.container);
            }
            if (valve instanceof Lifecycle) {
                try {
                    ((Lifecycle) valve).start();
                } catch (LifecycleException e) {
                    log.error("StandardPipeline.setBasic: start", e);
                    return;
                }
            }
    
            // Update the pipeline
            Valve current = first;
            while (current != null) {
                if (current.getNext() == oldBasic) {
                    current.setNext(valve);
                    break;
                }
                current = current.getNext();
            }
            
            this.basic = valve;
    
        }

    1.addValve

        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 (started) {
                if (valve instanceof Lifecycle) {
                    try {
                        ((Lifecycle) valve).start();
                    } catch (LifecycleException e) {
                        log.error("StandardPipeline.addValve: start: ", e);
                    }
                }
                // Register the newly added valve
                registerValve(valve);
            }
    
            // 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();
                }
            }
    
        }

    六。public interface Pipeline

    Interface describing a collection of Valves that should be executed in sequence when the invoke() method is invoked. It is required that

    a Valve somewhere in the pipeline (usually the last one) must process the request and create the corresponding response, rather than

    trying to pass the request on.

    There is generally a single Pipeline instance associated with each Container. The container's normal request processing functionality is

    generally encapsulated in a container-specific Valve, which should always be executed at the end of a pipeline. To facilitate this, the 

    setBasic() method is provided to set the Valve instance that will always be executed last. Other Valves will be executed in the order

    that they were added, before the basic Valve is executed.

  • 相关阅读:
    针对数据库索引的优化
    acd
    HDOJ 5045 Contest
    《计算机时代》2015年第7期刊登出《基于数据仓库星形模式的广东省快速公路一张网资金结算情况分析系统》
    为什么大多数编程语言中的数组都从0開始
    十年,青春就是一转眼的事
    电子商务系统的设计与实现(十四):菜单高亮
    最近1个月的财务计划没有做好,囧啊
    最近1个月的财务计划没有做好,囧啊
    雷观(十九):我的人生观
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/3984507.html
Copyright © 2011-2022 走看看