亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

How Tomcat Works(十五)

系統 1849 0

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

在創建StandardContext實例后,必須調用其start()方法來為引入的每個HTTP請求服務;其中包括讀取和解析默認的web.xml文件(該文件位于%CATALINA_HOME%/conf目錄),該文件的內容會應用到所有部署到tomcat中的應用程序中;此外,還會配置驗證器閥和許可閥。

StandardContext類使用一個事件監聽器來作為其配置器(前面我們已經學過在SimpleContextConfig事件監聽器中配置驗證器閥)

      
        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()方法里面,包括初始化相關容器組件、觸發相關事件等(ContextConfig監聽器會執行一些配置操作)

StandardContext類的invoke()方法由與其相關聯的連接器調用,或者當StandardContext實例是Host容器的子容器時,由Host實例的invoke()方法調用

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

    }
      
    

對于每個引入的HTTP請求,都會調用StandardContext實例的管道對象的基礎閥的invoke()方法來處理,這里是org.apache.catalina.core.StandardContextValve類的實例;StandardContextValve類的invoke()方法要做的第一件事是獲取一個要處理當前HTTP請求的Wrapper實例;StandardContextValve實例使用StandardContext實例的映射器找到一個合適的Wrapper實例,找到Wrapper實例后,它就會調用Wrapper實例的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實例必須與一個Context級的容器相關聯(在它的map()方法中調用了Context容器實例的相關方法)

standardContext類定義了reloadable屬性來指明該應用程序是否啟用了重載功能,當啟用重載功能后,當web.xml文件發生變化或WEB-INF/classes目錄下的文件被重新編譯后,應用程序會重載。

standardContext類是通過其載入器實現應用程序重載的,在tomcat4中,standardContext對象中的WebappLoader類實現了Loader接口,并使用另一個線程檢查WEB-INF目錄中的所有類和JAR文件的時間戳。只需要調用其setContainer()方法將WebappLoader對象與standardContext對象相關聯就可以啟動該檢查線程

下面是tomcat4中WebappLoader類的setContainer()方法的實現代碼

      
        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實例的reloadable屬性值與standardContext實例的reloadable屬性值是一致的

下面是WebappLoader類的setReloadable()方法的實現代碼:

      
        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()方法會啟動一個專用的線程來不斷地檢查WEB-INF目錄下的類和JAR文件的時間戳,而threadStop()方法則會終止該線程。

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

本系列How Tomcat Works系本人原創?

轉載請注明出處 博客園 刺猬的溫馴?

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

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

How Tomcat Works(十五)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 五十路一区二区三区视频 | 免费爽视频 | 日韩国产欧美一区二区三区 | 亚洲综合精品一区二区三区中文 | 免费播放欧美毛片欧美aaaaa | 亚洲爱婷婷色婷婷五月 | 免费视频一区二区三区四区 | 亚洲最色 | 国产香蕉在线 | 羞羞视频网页 | 在线观看精品国产 | 久久婷婷丁香七月色综合 | 日韩高清不卡在线 | 久久精品免费一区二区视 | 国产综合色在线视频区色吧图片 | 老司机午夜在线视频 | 一级毛片欧美一级日韩黄 | 色婷婷综合久久久久中文一区二区 | 精品中文字幕在线观看 | 久久免费国产精品一区二区 | 青青影院一区二区免费视频 | 中文字幕亚洲综合久久202 | 久久不射视频 | 欧美一级毛片免费观看 | 波多野结衣一区2区3区 | 亚洲精品乱码久久久久久中文字幕 | 成年人的毛片 | 伊人色综合久久天天 | 精品亚洲无人区一区二区 | 每日更新在线观看av | 亚洲精品国产福利 | 国产高清一区二区三区视频 | 久久久国产精品福利免费 | 免费真实播放国产乱子伦 | 在线看日本a毛片 | 日韩你懂得 | 色偷偷91久久综合噜噜噜 | 欧美视频性 | 日本一级特黄毛片免费视频9 | 久久r精品 | 久久精品国产日本波多麻结衣 |