日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

How Tomcat Works(十五)

系統(tǒng) 2154 0

本文接下來(lái)分析Context容器,Context容器實(shí)例表示一個(gè)具體的Web應(yīng)用程序,其中包括一個(gè)或多個(gè)Wrapper實(shí)例;不過Context容器還需要其他的組件支持,典型的如載入器和Session管理器等。

在創(chuàng)建StandardContext實(shí)例后,必須調(diào)用其start()方法來(lái)為引入的每個(gè)HTTP請(qǐng)求服務(wù);其中包括讀取和解析默認(rèn)的web.xml文件(該文件位于%CATALINA_HOME%/conf目錄),該文件的內(nèi)容會(huì)應(yīng)用到所有部署到tomcat中的應(yīng)用程序中;此外,還會(huì)配置驗(yàn)證器閥和許可閥。

StandardContext類使用一個(gè)事件監(jiān)聽器來(lái)作為其配置器(前面我們已經(jīng)學(xué)過在SimpleContextConfig事件監(jiān)聽器中配置驗(yàn)證器閥)

      
        public
      
      
        synchronized
      
      
        void
      
       start() 
      
        throws
      
      
         LifecycleException {
        
      
      
        if
      
      
         (started)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "containerBase.alreadyStarted"
      
        , logName()));

        
      
      
        if
      
       (debug >= 1
      
        )
            log(
      
      "Starting"
      
        );

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, 
      
        null
      
      
        );

        
      
      
        if
      
       (debug >= 1
      
        )
            log(
      
      "Processing start(), current available=" +
      
         getAvailable());
        setAvailable(
      
      
        false
      
      
        );
        setConfigured(
      
      
        false
      
      
        );
        
      
      
        boolean
      
       ok = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Add missing components as necessary
      
      
        if
      
       (getResources() == 
      
        null
      
      ) {   
      
        //
      
      
         (1) Required by Loader
      
      
        if
      
       (debug >= 1
      
        )
                log(
      
      "Configuring default Resources"
      
        );
            
      
      
        try
      
      
         {
                
      
      
        if
      
       ((docBase != 
      
        null
      
      ) && (docBase.endsWith(".war"
      
        )))
                    setResources(
      
      
        new
      
      
         WARDirContext());
                
      
      
        else
      
      
        
                    setResources(
      
      
        new
      
      
         FileDirContext());
            } 
      
      
        catch
      
      
         (IllegalArgumentException e) {
                log(
      
      "Error initializing resources: " +
      
         e.getMessage());
                ok 
      
      = 
      
        false
      
      
        ;
            }
        }
        
      
      
        if
      
       (ok && (resources 
      
        instanceof
      
      
         ProxyDirContext)) {
            DirContext dirContext 
      
      =
      
        
                ((ProxyDirContext) resources).getDirContext();
            
      
      
        if
      
       ((dirContext != 
      
        null
      
      
        )
                
      
      && (dirContext 
      
        instanceof
      
      
         BaseDirContext)) {
                ((BaseDirContext) dirContext).setDocBase(getBasePath());
                ((BaseDirContext) dirContext).allocate();
            }
        }
        
      
      
        if
      
       (getLoader() == 
      
        null
      
      ) {      
      
        //
      
      
         (2) Required by Manager
      
      
        if
      
      
         (getPrivileged()) {
                
      
      
        if
      
       (debug >= 1
      
        )
                    log(
      
      "Configuring privileged default Loader"
      
        );
                setLoader(
      
      
        new
      
       WebappLoader(
      
        this
      
      
        .getClass().getClassLoader()));
            } 
      
      
        else
      
      
         {
                
      
      
        if
      
       (debug >= 1
      
        )
                    log(
      
      "Configuring non-privileged default Loader"
      
        );
                setLoader(
      
      
        new
      
      
         WebappLoader(getParentClassLoader()));
            }
        }
        
      
      
        if
      
       (getManager() == 
      
        null
      
      ) {     
      
        //
      
      
         (3) After prerequisites
      
      
        if
      
       (debug >= 1
      
        )
                log(
      
      "Configuring default Manager"
      
        );
            setManager(
      
      
        new
      
      
         StandardManager());
        }

        
      
      
        //
      
      
         Initialize character set mapper
      
      
                getCharsetMapper();

        
      
      
        //
      
      
         Post work directory
      
      
                postWorkDirectory();

        
      
      
        //
      
      
         Reading the "catalina.useNaming" environment variable
      
      
        String useNamingProperty = System.getProperty("catalina.useNaming"
      
        );
        
      
      
        if
      
       ((useNamingProperty != 
      
        null
      
      
        )
            
      
      && (useNamingProperty.equals("false"
      
        ))) {
            useNaming 
      
      = 
      
        false
      
      
        ;
        }

        
      
      
        if
      
       (ok &&
      
         isUseNaming()) {
            
      
      
        if
      
       (namingContextListener == 
      
        null
      
      
        ) {
                namingContextListener 
      
      = 
      
        new
      
      
         NamingContextListener();
                namingContextListener.setDebug(getDebug());
                namingContextListener.setName(getNamingContextName());
                addLifecycleListener(namingContextListener);
            }
        }

        
      
      
        //
      
      
         Binding thread
      
      
        ClassLoader oldCCL =
      
         bindThread();

        
      
      
        //
      
      
         Standard container startup
      
      
        if
      
       (debug >= 1
      
        )
            log(
      
      "Processing standard container startup"
      
        );

        
      
      
        if
      
      
         (ok) {

            
      
      
        try
      
      
         {

                addDefaultMapper(
      
      
        this
      
      
        .mapperClass);
                started 
      
      = 
      
        true
      
      
        ;

                
      
      
        //
      
      
         Start our subordinate components, if any
      
      
        if
      
       ((loader != 
      
        null
      
      ) && (loader 
      
        instanceof
      
      
         Lifecycle))
                    ((Lifecycle) loader).start();
                
      
      
        if
      
       ((logger != 
      
        null
      
      ) && (logger 
      
        instanceof
      
      
         Lifecycle))
                    ((Lifecycle) logger).start();

                
      
      
        //
      
      
         Unbinding thread
      
      
                        unbindThread(oldCCL);

                
      
      
        //
      
      
         Binding thread
      
      
                oldCCL =
      
         bindThread();

                
      
      
        if
      
       ((cluster != 
      
        null
      
      ) && (cluster 
      
        instanceof
      
      
         Lifecycle))
                    ((Lifecycle) cluster).start();
                
      
      
        if
      
       ((realm != 
      
        null
      
      ) && (realm 
      
        instanceof
      
      
         Lifecycle))
                    ((Lifecycle) realm).start();
                
      
      
        if
      
       ((resources != 
      
        null
      
      ) && (resources 
      
        instanceof
      
      
         Lifecycle))
                    ((Lifecycle) resources).start();

                
      
      
        //
      
      
         Start our Mappers, if any
      
      
                Mapper mappers[] =
      
         findMappers();
                
      
      
        for
      
       (
      
        int
      
       i = 0; i < mappers.length; i++
      
        ) {
                    
      
      
        if
      
       (mappers[i] 
      
        instanceof
      
      
         Lifecycle)
                        ((Lifecycle) mappers[i]).start();
                }

                
      
      
        //
      
      
         Start our child containers, if any
      
      
                Container children[] =
      
         findChildren();
                
      
      
        for
      
       (
      
        int
      
       i = 0; i < children.length; i++
      
        ) {
                    
      
      
        if
      
       (children[i] 
      
        instanceof
      
      
         Lifecycle)
                        ((Lifecycle) children[i]).start();
                }

                
      
      
        //
      
      
         Start the Valves in our pipeline (including the basic),
                
      
      
        //
      
      
         if any
      
      
        if
      
       (pipeline 
      
        instanceof
      
      
         Lifecycle)
                    ((Lifecycle) pipeline).start();

                
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
                lifecycle.fireLifecycleEvent(START_EVENT, 
      
        null
      
      
        );

                
      
      
        if
      
       ((manager != 
      
        null
      
      ) && (manager 
      
        instanceof
      
      
         Lifecycle))
                    ((Lifecycle) manager).start();

            } 
      
      
        finally
      
      
         {
                
      
      
        //
      
      
         Unbinding thread
      
      
                        unbindThread(oldCCL);
            }

        }
        
      
      
        if
      
       (!
      
        getConfigured())
            ok 
      
      = 
      
        false
      
      
        ;

        
      
      
        //
      
      
         We put the resources into the servlet context
      
      
        if
      
      
         (ok)
            getServletContext().setAttribute
                (Globals.RESOURCES_ATTR, getResources());

        
      
      
        //
      
      
         Binding thread
      
      
        oldCCL =
      
         bindThread();

        
      
      
        //
      
      
         Create context attributes that will be required
      
      
        if
      
      
         (ok) {
            
      
      
        if
      
       (debug >= 1
      
        )
                log(
      
      "Posting standard context attributes"
      
        );
            postWelcomeFiles();
        }

        
      
      
        //
      
      
         Configure and call application event listeners and filters
      
      
        if
      
      
         (ok) {
            
      
      
        if
      
       (!
      
        listenerStart())
                ok 
      
      = 
      
        false
      
      
        ;
        }
        
      
      
        if
      
      
         (ok) {
            
      
      
        if
      
       (!
      
        filterStart())
                ok 
      
      = 
      
        false
      
      
        ;
        }

        
      
      
        //
      
      
         Load and initialize all "load on startup" servlets
      
      
        if
      
      
         (ok)
            loadOnStartup(findChildren());

        
      
      
        //
      
      
         Unbinding thread
      
      
                unbindThread(oldCCL);

        
      
      
        //
      
      
         Set available status depending upon startup success
      
      
        if
      
      
         (ok) {
            
      
      
        if
      
       (debug >= 1
      
        )
                log(
      
      "Starting completed"
      
        );
            setAvailable(
      
      
        true
      
      
        );
        } 
      
      
        else
      
      
         {
            log(sm.getString(
      
      "standardContext.startFailed"
      
        ));
            
      
      
        try
      
      
         {
                stop();
            } 
      
      
        catch
      
      
         (Throwable t) {
                log(sm.getString(
      
      "standardContext.startCleanup"
      
        ), t);
            }
            setAvailable(
      
      
        false
      
      
        );
        }

        
      
      
        //
      
      
         Notify our interested LifecycleListeners
      
      
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, 
      
        null
      
      
        );

    }
      
    

在它的start()方法里面,包括初始化相關(guān)容器組件、觸發(fā)相關(guān)事件等(ContextConfig監(jiān)聽器會(huì)執(zhí)行一些配置操作)

StandardContext類的invoke()方法由與其相關(guān)聯(lián)的連接器調(diào)用,或者當(dāng)StandardContext實(shí)例是Host容器的子容器時(shí),由Host實(shí)例的invoke()方法調(diào)用

      
        public
      
      
        void
      
      
         invoke(Request request, Response response)
        
      
      
        throws
      
      
         IOException, ServletException {

        
      
      
        //
      
      
         Wait if we are reloading
      
      
        while
      
      
         (getPaused()) {
            
      
      
        try
      
      
         {
                Thread.sleep(
      
      1000
      
        );
            } 
      
      
        catch
      
      
         (InterruptedException e) {
                ;
            }
        }

        
      
      
        //
      
      
         Normal request processing
      
      
        if
      
      
         (swallowOutput) {
            
      
      
        try
      
      
         {
                SystemLogHandler.startCapture();
                
      
      
        super
      
      
        .invoke(request, response);
            } 
      
      
        finally
      
      
         {
                String log 
      
      =
      
         SystemLogHandler.stopCapture();
                
      
      
        if
      
       (log != 
      
        null
      
       && log.length() > 0
      
        ) {
                    log(log);
                }
            }
        } 
      
      
        else
      
      
         {
            
      
      
        super
      
      
        .invoke(request, response);
        }

    }
      
    

對(duì)于每個(gè)引入的HTTP請(qǐng)求,都會(huì)調(diào)用StandardContext實(shí)例的管道對(duì)象的基礎(chǔ)閥的invoke()方法來(lái)處理,這里是org.apache.catalina.core.StandardContextValve類的實(shí)例;StandardContextValve類的invoke()方法要做的第一件事是獲取一個(gè)要處理當(dāng)前HTTP請(qǐng)求的Wrapper實(shí)例;StandardContextValve實(shí)例使用StandardContext實(shí)例的映射器找到一個(gè)合適的Wrapper實(shí)例,找到Wrapper實(shí)例后,它就會(huì)調(diào)用Wrapper實(shí)例的invoke()方法

下面是standardContextMapper類的map()方法

      
        public
      
       Container map(Request request, 
      
        boolean
      
      
         update) {


        
      
      
        int
      
       debug =
      
         context.getDebug();

        
      
      
        //
      
      
         Has this request already been mapped?
      
      
        if
      
       (update && (request.getWrapper() != 
      
        null
      
      
        ))
            
      
      
        return
      
      
         (request.getWrapper());

        
      
      
        //
      
      
         Identify the context-relative URI to be mapped
      
      
        String contextPath =
      
        
            ((HttpServletRequest) request.getRequest()).getContextPath();
        String requestURI 
      
      =
      
         ((HttpRequest) request).getDecodedRequestURI();
        String relativeURI 
      
      =
      
         requestURI.substring(contextPath.length());


        
      
      
        if
      
       (debug >= 1
      
        )
            context.log(
      
      "Mapping contextPath='" + contextPath +
                        "' with requestURI='" + requestURI +
                        "' and relativeURI='" + relativeURI + "'"
      
        );

        
      
      
        //
      
      
         Apply the standard request URI mapping rules from the specification
      
      
        Wrapper wrapper = 
      
        null
      
      
        ;
        String servletPath 
      
      =
      
         relativeURI;
        String pathInfo 
      
      = 
      
        null
      
      
        ;
        String name 
      
      = 
      
        null
      
      
        ;

        
      
      
        //
      
      
         Rule 1 -- Exact Match
      
      
        if
      
       (wrapper == 
      
        null
      
      
        ) {
            
      
      
        if
      
       (debug >= 2
      
        )
                context.log(
      
      "  Trying exact match"
      
        );
            
      
      
        if
      
       (!(relativeURI.equals("/"
      
        )))
                name 
      
      =
      
         context.findServletMapping(relativeURI);
            
      
      
        if
      
       (name != 
      
        null
      
      
        )
                wrapper 
      
      =
      
         (Wrapper) context.findChild(name);
            
      
      
        if
      
       (wrapper != 
      
        null
      
      
        ) {
                servletPath 
      
      =
      
         relativeURI;
                pathInfo 
      
      = 
      
        null
      
      
        ;
            }
        }

        
      
      
        //
      
      
         Rule 2 -- Prefix Match
      
      
        if
      
       (wrapper == 
      
        null
      
      
        ) {
            
      
      
        if
      
       (debug >= 2
      
        )
                context.log(
      
      "  Trying prefix match"
      
        );
            servletPath 
      
      =
      
         relativeURI;
            
      
      
        while
      
       (
      
        true
      
      
        ) {
                name 
      
      = context.findServletMapping(servletPath + "/*"
      
        );
                
      
      
        if
      
       (name != 
      
        null
      
      
        )
                    wrapper 
      
      =
      
         (Wrapper) context.findChild(name);
                
      
      
        if
      
       (wrapper != 
      
        null
      
      
        ) {
                    pathInfo 
      
      =
      
         relativeURI.substring(servletPath.length());
                    
      
      
        if
      
       (pathInfo.length() == 0
      
        )
                        pathInfo 
      
      = 
      
        null
      
      
        ;
                    
      
      
        break
      
      
        ;
                }
                
      
      
        int
      
       slash = servletPath.lastIndexOf('/'
      
        );
                
      
      
        if
      
       (slash < 0
      
        )
                    
      
      
        break
      
      
        ;
                servletPath 
      
      = servletPath.substring(0
      
        , slash);
            }
        }

        
      
      
        //
      
      
         Rule 3 -- Extension Match
      
      
        if
      
       (wrapper == 
      
        null
      
      
        ) {
            
      
      
        if
      
       (debug >= 2
      
        )
                context.log(
      
      "  Trying extension match"
      
        );
            
      
      
        int
      
       slash = relativeURI.lastIndexOf('/'
      
        );
            
      
      
        if
      
       (slash >= 0
      
        ) {
                String last 
      
      =
      
         relativeURI.substring(slash);
                
      
      
        int
      
       period = last.lastIndexOf('.'
      
        );
                
      
      
        if
      
       (period >= 0
      
        ) {
                    String pattern 
      
      = "*" +
      
         last.substring(period);
                    name 
      
      =
      
         context.findServletMapping(pattern);
                    
      
      
        if
      
       (name != 
      
        null
      
      
        )
                        wrapper 
      
      =
      
         (Wrapper) context.findChild(name);
                    
      
      
        if
      
       (wrapper != 
      
        null
      
      
        ) {
                        servletPath 
      
      =
      
         relativeURI;
                        pathInfo 
      
      = 
      
        null
      
      
        ;
                    }
                }
            }
        }

        
      
      
        //
      
      
         Rule 4 -- Default Match
      
      
        if
      
       (wrapper == 
      
        null
      
      
        ) {
            
      
      
        if
      
       (debug >= 2
      
        )
                context.log(
      
      "  Trying default match"
      
        );
            name 
      
      = context.findServletMapping("/"
      
        );
            
      
      
        if
      
       (name != 
      
        null
      
      
        )
                wrapper 
      
      =
      
         (Wrapper) context.findChild(name);
            
      
      
        if
      
       (wrapper != 
      
        null
      
      
        ) {
                servletPath 
      
      =
      
         relativeURI;
                pathInfo 
      
      = 
      
        null
      
      
        ;
            }
        }

        
      
      
        //
      
      
         Update the Request (if requested) and return this Wrapper
      
      
        if
      
       ((debug >= 1) && (wrapper != 
      
        null
      
      
        ))
            context.log(
      
      " Mapped to servlet '" + wrapper.getName() +
                        "' with servlet path '" + servletPath +
                        "' and path info '" + pathInfo +
                        "' and update=" +
      
         update);
        
      
      
        if
      
      
         (update) {
            request.setWrapper(wrapper);
            ((HttpRequest) request).setServletPath(servletPath);
            ((HttpRequest) request).setPathInfo(pathInfo);
        }
        
      
      
        return
      
      
         (wrapper);

    }
      
    

standardContextMapper實(shí)例必須與一個(gè)Context級(jí)的容器相關(guān)聯(lián)(在它的map()方法中調(diào)用了Context容器實(shí)例的相關(guān)方法)

standardContext類定義了reloadable屬性來(lái)指明該應(yīng)用程序是否啟用了重載功能,當(dāng)啟用重載功能后,當(dāng)web.xml文件發(fā)生變化或WEB-INF/classes目錄下的文件被重新編譯后,應(yīng)用程序會(huì)重載。

standardContext類是通過其載入器實(shí)現(xiàn)應(yīng)用程序重載的,在tomcat4中,standardContext對(duì)象中的WebappLoader類實(shí)現(xiàn)了Loader接口,并使用另一個(gè)線程檢查WEB-INF目錄中的所有類和JAR文件的時(shí)間戳。只需要調(diào)用其setContainer()方法將WebappLoader對(duì)象與standardContext對(duì)象相關(guān)聯(lián)就可以啟動(dòng)該檢查線程

下面是tomcat4中WebappLoader類的setContainer()方法的實(shí)現(xiàn)代碼

      
        public
      
      
        void
      
      
         setContainer(Container container) {

        
      
      
        //
      
      
         Deregister from the old Container (if any)
      
      
        if
      
       ((
      
        this
      
      .container != 
      
        null
      
      ) && (
      
        this
      
      .container 
      
        instanceof
      
      
         Context))
            ((Context) 
      
      
        this
      
      .container).removePropertyChangeListener(
      
        this
      
      
        );

        
      
      
        //
      
      
         Process this property change
      
      
        Container oldContainer = 
      
        this
      
      
        .container;
        
      
      
        this
      
      .container =
      
         container;
        support.firePropertyChange(
      
      "container", oldContainer, 
      
        this
      
      
        .container);

        
      
      
        //
      
      
         Register with the new Container (if any)
      
      
        if
      
       ((
      
        this
      
      .container != 
      
        null
      
      ) && (
      
        this
      
      .container 
      
        instanceof
      
      
         Context)) {
            setReloadable( ((Context) 
      
      
        this
      
      
        .container).getReloadable() );
            ((Context) 
      
      
        this
      
      .container).addPropertyChangeListener(
      
        this
      
      
        );
        }

    }
      
    

WebappLoader實(shí)例的reloadable屬性值與standardContext實(shí)例的reloadable屬性值是一致的

下面是WebappLoader類的setReloadable()方法的實(shí)現(xiàn)代碼:

      
        public
      
      
        void
      
       setReloadable(
      
        boolean
      
      
         reloadable) {

        
      
      
        //
      
      
         Process this property change
      
      
        boolean
      
       oldReloadable = 
      
        this
      
      
        .reloadable;
        
      
      
        this
      
      .reloadable =
      
         reloadable;
        support.firePropertyChange(
      
      "reloadable"
      
        ,
                                   
      
      
        new
      
      
         Boolean(oldReloadable),
                                   
      
      
        new
      
       Boolean(
      
        this
      
      
        .reloadable));

        
      
      
        //
      
      
         Start or stop our background thread if required
      
      
        if
      
       (!
      
        started)
            
      
      
        return
      
      
        ;
        
      
      
        if
      
       (!oldReloadable && 
      
        this
      
      
        .reloadable)
            threadStart();
        
      
      
        else
      
      
        if
      
       (oldReloadable && !
      
        this
      
      
        .reloadable)
            threadStop();

    }
      
    

里面的threadStart()方法會(huì)啟動(dòng)一個(gè)專用的線程來(lái)不斷地檢查WEB-INF目錄下的類和JAR文件的時(shí)間戳,而threadStop()方法則會(huì)終止該線程。

---------------------------------------------------------------------------?

本系列How Tomcat Works系本人原創(chuàng)?

轉(zhuǎn)載請(qǐng)注明出處 博客園 刺猬的溫馴?

本人郵箱: ? chenying998179 # 163.com ( #改為@

本文鏈接 http://www.cnblogs.com/chenying99/p/3242279.html

How Tomcat Works(十五)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!?。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 航空| 安乡县| 清远市| 沅陵县| 耿马| 渑池县| 平果县| 湟源县| 襄樊市| 柘荣县| 九龙坡区| 伊川县| 运城市| 襄垣县| 西吉县| 孟州市| 广安市| 巫溪县| 牡丹江市| 云龙县| 萝北县| 射洪县| 资溪县| 涪陵区| 红河县| 额敏县| 兴山县| 石屏县| 余庆县| 四会市| 乐安县| 朔州市| 驻马店市| 嘉峪关市| 集安市| 祥云县| 怀宁县| 建瓯市| 沙河市| 仁布县| 禹城市|