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

How Tomcat Works(十四)

系統(tǒng) 2162 0

我們已經(jīng)知道,在tomcat中有四種類型的servlet容器,分別為Engine、Host、Context 和Wrapper,本文接下來(lái)對(duì)tomcat中Wrapper接口的標(biāo)準(zhǔn)實(shí)現(xiàn)進(jìn)行說(shuō)明。

對(duì)于每個(gè)引入的HTTP請(qǐng)求,連接器都會(huì)調(diào)用與其關(guān)聯(lián)的servlet容器的invoke()方法;然后,servlet容器會(huì)調(diào)用所有子容器的invoke()方法

這里面的流程通常是servlet容器調(diào)用其管道對(duì)象的invoke()方法,其管道對(duì)象的invoke()方法最后調(diào)用其基礎(chǔ)閥,管道對(duì)象的基礎(chǔ)閥里面會(huì)調(diào)用子容器的invoke()方法;子容器的invoke()方法的調(diào)用序列與之相同。

在tomcat中,servlet類可以實(shí)現(xiàn)javax.servlet.SingleThreadModel接口,這樣的servlet類也稱為SingleThreadModel(STM)servlet類;根據(jù)Servlet規(guī)范,實(shí)現(xiàn)此接口的目的是保證servlet實(shí)例一次只處理一個(gè)請(qǐng)求。

StandardWrapper對(duì)象的主要任務(wù)是載入它所代表的servlet類,并進(jìn)行實(shí)例化;不過StandardWrapper類并不調(diào)用servlet的service方法,該任務(wù)由StandardWrapperValve對(duì)象(StandardWrapper實(shí)例的管道對(duì)象中的基礎(chǔ)閥)完成;StandardWrapperValve對(duì)象通過調(diào)用StandardWrapper實(shí)例的allocate()方法獲取servlet實(shí)例,在獲取實(shí)例后,StandardWrapperValve實(shí)例就會(huì)調(diào)用servlet實(shí)例的service()方法

對(duì)于STM 類型的servlet類與非STM 類型的servlet類,StandardWrapper實(shí)例的載入方式是不一樣的;對(duì)于非STM 類型的servlet類,StandardWrapper實(shí)例只會(huì)載入一次,對(duì)于隨后的請(qǐng)求都會(huì)返回servlet的同一個(gè)實(shí)例,它假設(shè)該servlet類的service()方法在多線程環(huán)境中是線程安全的。

而對(duì)于STM 類型的servlet類,StandardWrapper實(shí)例必須保證每一時(shí)刻只能有一個(gè)線程在執(zhí)行STM servlet類的service()方法;StandardWrapper實(shí)例通過將STM 類型的servlet實(shí)例保存在一個(gè)java.util.Stack類型的棧中

      
        public
      
       Servlet allocate() 
      
        throws
      
      
         ServletException {

        
      
      
        if
      
       (debug >= 1
      
        )
            log(
      
      "Allocating an instance"
      
        );

        
      
      
        //
      
      
         If we are currently unloading this servlet, throw an exception
      
      
        if
      
      
         (unloading)
            
      
      
        throw
      
      
        new
      
      
         ServletException
              (sm.getString(
      
      "standardWrapper.unloading"
      
        , getName()));

        
      
      
        //
      
      
         If not SingleThreadedModel, return the same instance every time
      
      
        if
      
       (!
      
        singleThreadModel) {

            
      
      
        //
      
      
         Load and initialize our instance if necessary
      
      
        if
      
       (instance == 
      
        null
      
      
        ) {
                
      
      
        synchronized
      
       (
      
        this
      
      
        ) {
                    
      
      
        if
      
       (instance == 
      
        null
      
      
        ) {
                        
      
      
        try
      
      
         {
                            instance 
      
      =
      
         loadServlet();
                        } 
      
      
        catch
      
      
         (ServletException e) {
                            
      
      
        throw
      
      
         e;
                        } 
      
      
        catch
      
      
         (Throwable e) {
                            
      
      
        throw
      
      
        new
      
      
         ServletException
                                (sm.getString(
      
      "standardWrapper.allocate"
      
        ), e);
                        }
                    }
                }
            }

            
      
      
        if
      
       (!
      
        singleThreadModel) {
                
      
      
        if
      
       (debug >= 2
      
        )
                    log(
      
      "  Returning non-STM instance"
      
        );
                countAllocated
      
      ++
      
        ;
                
      
      
        return
      
      
         (instance);
            }

        }

        
      
      
        synchronized
      
      
         (instancePool) {

            
      
      
        while
      
       (countAllocated >=
      
         nInstances) {
                
      
      
        //
      
      
         Allocate a new instance if possible, or else wait
      
      
        if
      
       (nInstances <
      
         maxInstances) {
                    
      
      
        try
      
      
         {
                        instancePool.push(loadServlet());
                        nInstances
      
      ++
      
        ;
                    } 
      
      
        catch
      
      
         (ServletException e) {
                        
      
      
        throw
      
      
         e;
                    } 
      
      
        catch
      
      
         (Throwable e) {
                        
      
      
        throw
      
      
        new
      
      
         ServletException
                            (sm.getString(
      
      "standardWrapper.allocate"
      
        ), e);
                    }
                } 
      
      
        else
      
      
         {
                    
      
      
        try
      
      
         {
                        instancePool.wait();
                    } 
      
      
        catch
      
      
         (InterruptedException e) {
                        ;
                    }
                }
            }
            
      
      
        if
      
       (debug >= 2
      
        )
                log(
      
      "  Returning allocated STM instance"
      
        );
            countAllocated
      
      ++
      
        ;
            
      
      
        return
      
      
         (Servlet) instancePool.pop();

        }

    }
      
    

而在loadServlet()方法中,首先獲取要加載的servlet的完整類名及類加載器,然后通過類加載器加載該servlet類,然后實(shí)例化該servlet類,最后調(diào)用該servlet實(shí)例的init()方法初始化(傳入javax.servlet.ServletConfig對(duì)象)

      
        public
      
      
        synchronized
      
       Servlet loadServlet() 
      
        throws
      
      
         ServletException {

        
      
      
        //
      
      
         Nothing to do if we already have an instance or an instance pool
      
      
        if
      
       (!singleThreadModel && (instance != 
      
        null
      
      
        ))
            
      
      
        return
      
      
         instance;

        PrintStream out 
      
      =
      
         System.out;
        SystemLogHandler.startCapture();
        Servlet servlet 
      
      = 
      
        null
      
      
        ;
        
      
      
        try
      
      
         {
            
      
      
        //
      
      
         If this "servlet" is really a JSP file, get the right class.
            
      
      
        //
      
      
         HOLD YOUR NOSE - this is a kludge that avoids having to do special
            
      
      
        //
      
      
         case Catalina-specific code in Jasper - it also requires that the
            
      
      
        //
      
      
         servlet path be replaced by the <jsp-file> element content in
            
      
      
        //
      
      
         order to be completely effective
      
      
            String actualClass =
      
         servletClass;
            
      
      
        if
      
       ((actualClass == 
      
        null
      
      ) && (jspFile != 
      
        null
      
      
        )) {
                Wrapper jspWrapper 
      
      =
      
         (Wrapper)
                    ((Context) getParent()).findChild(Constants.JSP_SERVLET_NAME);
                
      
      
        if
      
       (jspWrapper != 
      
        null
      
      
        )
                    actualClass 
      
      =
      
         jspWrapper.getServletClass();
            }

            
      
      
        //
      
      
         Complain if no servlet class has been specified
      
      
        if
      
       (actualClass == 
      
        null
      
      
        ) {
                unavailable(
      
      
        null
      
      
        );
                
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.notClass"
      
        , getName()));
            }

            
      
      
        //
      
      
         Acquire an instance of the class loader to be used
      
      
            Loader loader =
      
         getLoader();
            
      
      
        if
      
       (loader == 
      
        null
      
      
        ) {
                unavailable(
      
      
        null
      
      
        );
                
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.missingLoader"
      
        , getName()));
            }

            ClassLoader classLoader 
      
      =
      
         loader.getClassLoader();

            
      
      
        //
      
      
         Special case class loader for a container provided servlet
      
      
        if
      
      
         (isContainerProvidedServlet(actualClass)) {
                classLoader 
      
      = 
      
        this
      
      
        .getClass().getClassLoader();
                log(sm.getString
                      (
      
      "standardWrapper.containerServlet"
      
        , getName()));
            }

            
      
      
        //
      
      
         Load the specified servlet class from the appropriate class loader
      
      
            Class classClass = 
      
        null
      
      
        ;
            
      
      
        try
      
      
         {
                
      
      
        if
      
       (classLoader != 
      
        null
      
      
        ) {
                    System.out.println(
      
      "Using classLoader.loadClass"
      
        );
                    classClass 
      
      =
      
         classLoader.loadClass(actualClass);
                } 
      
      
        else
      
      
         {
                    System.out.println(
      
      "Using forName"
      
        );
                    classClass 
      
      =
      
         Class.forName(actualClass);
                }
            } 
      
      
        catch
      
      
         (ClassNotFoundException e) {
                unavailable(
      
      
        null
      
      
        );
                
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.missingClass"
      
        , actualClass),
                     e);
            }
            
      
      
        if
      
       (classClass == 
      
        null
      
      
        ) {
                unavailable(
      
      
        null
      
      
        );
                
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.missingClass"
      
        , actualClass));
            }

            
      
      
        //
      
      
         Instantiate and initialize an instance of the servlet class itself
      
      
        try
      
      
         {
                servlet 
      
      =
      
         (Servlet) classClass.newInstance();
            } 
      
      
        catch
      
      
         (ClassCastException e) {
                unavailable(
      
      
        null
      
      
        );
                
      
      
        //
      
      
         Restore the context ClassLoader
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.notServlet"
      
        , actualClass), e);
            } 
      
      
        catch
      
      
         (Throwable e) {
                unavailable(
      
      
        null
      
      
        );
                
      
      
        //
      
      
         Restore the context ClassLoader
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.instantiate"
      
        , actualClass), e);
            }

            
      
      
        //
      
      
         Check if loading the servlet in this web application should be
            
      
      
        //
      
      
         allowed
      
      
        if
      
       (!
      
        isServletAllowed(servlet)) {
                
      
      
        throw
      
      
        new
      
      
         SecurityException
                    (sm.getString(
      
      "standardWrapper.privilegedServlet"
      
        ,
                                  actualClass));
            }

            
      
      
        //
      
      
         Special handling for ContainerServlet instances
      
      
        if
      
       ((servlet 
      
        instanceof
      
       ContainerServlet) &&
      
        
                isContainerProvidedServlet(actualClass)) {
System.out.println(
      
      "calling setWrapper"
      
        );                  
                ((ContainerServlet) servlet).setWrapper(
      
      
        this
      
      
        );
System.out.println(
      
      "after calling setWrapper"
      
        );                  
            }


            
      
      
        //
      
      
         Call the initialization method of this servlet
      
      
        try
      
      
         {
                instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT,
                                                  servlet);
                servlet.init(facade);
                
      
      
        //
      
      
         Invoke jspInit on JSP pages
      
      
        if
      
       ((loadOnStartup > 0) && (jspFile != 
      
        null
      
      
        )) {
                    
      
      
        //
      
      
         Invoking jspInit
      
      
                    HttpRequestBase req = 
      
        new
      
      
         HttpRequestBase();
                    HttpResponseBase res 
      
      = 
      
        new
      
      
         HttpResponseBase();
                    req.setServletPath(jspFile);
                    req.setQueryString(
      
      "jsp_precompile=true"
      
        );
                    servlet.service(req, res);
                }
                instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT,
                                                  servlet);
            } 
      
      
        catch
      
      
         (UnavailableException f) {
                instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT,
                                                  servlet, f);
                unavailable(f);
                
      
      
        throw
      
      
         f;
            } 
      
      
        catch
      
      
         (ServletException f) {
                instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT,
                                                  servlet, f);
                
      
      
        //
      
      
         If the servlet wanted to be unavailable it would have
                
      
      
        //
      
      
         said so, so do not call unavailable(null).
      
      
        throw
      
      
         f;
            } 
      
      
        catch
      
      
         (Throwable f) {
                instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT,
                                                  servlet, f);
                
      
      
        //
      
      
         If the servlet wanted to be unavailable it would have
                
      
      
        //
      
      
         said so, so do not call unavailable(null).
      
      
        throw
      
      
        new
      
      
         ServletException
                    (sm.getString(
      
      "standardWrapper.initException"
      
        , getName()), f);
            }

            
      
      
        //
      
      
         Register our newly initialized instance
      
      
            singleThreadModel = servlet 
      
        instanceof
      
      
         SingleThreadModel;
            
      
      
        if
      
      
         (singleThreadModel) {
                
      
      
        if
      
       (instancePool == 
      
        null
      
      
        )
                    instancePool 
      
      = 
      
        new
      
      
         Stack();
            }
            fireContainerEvent(
      
      "load", 
      
        this
      
      
        );
        } 
      
      
        finally
      
      
         {
            String log 
      
      =
      
         SystemLogHandler.stopCapture();
            
      
      
        if
      
       (log != 
      
        null
      
       && log.length() > 0
      
        ) {
                
      
      
        if
      
       (getServletContext() != 
      
        null
      
      
        ) {
                    getServletContext().log(log);
                } 
      
      
        else
      
      
         {
                    out.println(log);
                }
            }
        }
        
      
      
        return
      
      
         servlet;

    }
      
    

?StandardWrapper類的loadServlet()方法在載入servlet類后,會(huì)調(diào)用該servlet實(shí)例的init()方法,該方法需要傳入一個(gè)javax.servlet.ServletConfig實(shí)例作為參數(shù);那么,?StandardWrapper對(duì)象是如何獲取ServletConfig對(duì)象的呢

答案就在StandardWrapper類本身,該類不僅實(shí)現(xiàn)了Wrapper接口,還實(shí)現(xiàn)了javax.servlet.ServletConfig接口,下面是相關(guān)方法實(shí)現(xiàn)

      
        /**
      
      
        
     * Return the initialization parameter value for the specified name,
     * if any; otherwise return <code>null</code>.
     *
     * 
      
      
        @param
      
      
         name Name of the initialization parameter to retrieve
     
      
      
        */
      
      
        public
      
      
         String getInitParameter(String name) {

        
      
      
        return
      
      
         (findInitParameter(name));

    }


    
      
      
        /**
      
      
        
     * Return the set of initialization parameter names defined for this
     * servlet.  If none are defined, an empty Enumeration is returned.
     
      
      
        */
      
      
        public
      
      
         Enumeration getInitParameterNames() {

        
      
      
        synchronized
      
      
         (parameters) {
            
      
      
        return
      
       (
      
        new
      
      
         Enumerator(parameters.keySet()));
        }

    }


    
      
      
        /**
      
      
        
     * Return the servlet context with which this servlet is associated.
     
      
      
        */
      
      
        public
      
      
         ServletContext getServletContext() {

        
      
      
        if
      
       (parent == 
      
        null
      
      
        )
            
      
      
        return
      
       (
      
        null
      
      
        );
        
      
      
        else
      
      
        if
      
       (!(parent 
      
        instanceof
      
      
         Context))
            
      
      
        return
      
       (
      
        null
      
      
        );
        
      
      
        else
      
      
        return
      
      
         (((Context) parent).getServletContext());

    }


    
      
      
        /**
      
      
        
     * Return the name of this servlet.
     
      
      
        */
      
      
        public
      
      
         String getServletName() {

        
      
      
        return
      
      
         (getName());

    }
      
    

StandardWrapper實(shí)例在它的loadServlet()方法里面調(diào)用它所載入的servlet類的實(shí)例的init()方法,該方法需要一個(gè)javax.servlet.ServletConfig類型參數(shù),理論上StandardWrapper對(duì)象可以將自身傳入init()方法,不過為了類型安全,StandardWrapper類將自身實(shí)例包裝成StandardWrapperFacade類的一個(gè)實(shí)例,然后再傳給init()方法

      
        public
      
      
        final
      
      
        class
      
      
         StandardWrapperFacade
    
      
      
        implements
      
      
         ServletConfig {
    
      
      
        /**
      
      
        
     * Create a new facede around a StandardWrapper.
     
      
      
        */
      
      
        public
      
      
         StandardWrapperFacade(StandardWrapper config) {

        
      
      
        super
      
      
        ();
        
      
      
        this
      
      .config =
      
         (ServletConfig) config;

    }
      
      
        /**
      
      
        
     * Wrapped config.
     
      
      
        */
      
      
        private
      
       ServletConfig config = 
      
        null
      
      
        ;
      
      
        public
      
      
         String getServletName() {
        
      
      
        return
      
      
         config.getServletName();
    }

    
      
      
        public
      
      
         ServletContext getServletContext() {
        ServletContext theContext 
      
      =
      
         config.getServletContext();
        
      
      
        if
      
       ((theContext != 
      
        null
      
      ) &&
      
        
            (theContext 
      
      
        instanceof
      
      
         ApplicationContext))
            theContext 
      
      =
      
         ((ApplicationContext) theContext).getFacade();
        
      
      
        return
      
      
         (theContext);
    }

    
      
      
        public
      
      
         String getInitParameter(String name) {
        
      
      
        return
      
      
         config.getInitParameter(name);
    }

    
      
      
        public
      
      
         Enumeration getInitParameterNames() {
        
      
      
        return
      
      
         config.getInitParameterNames();
    }

}
      
    

StandardWrapperValve類是StandardWrapper實(shí)例中的基礎(chǔ)閥,要完成兩個(gè)操作

(1)執(zhí)行與該servlet相關(guān)聯(lián)的全部過濾器

(2)調(diào)用servlet實(shí)例的service()方法

      
        public
      
      
        void
      
      
         invoke(Request request, Response response,
                       ValveContext valveContext)
        
      
      
        throws
      
      
         IOException, ServletException {
        
      
      
        //
      
      
         Initialize local variables we may need
      
      
        boolean
      
       unavailable = 
      
        false
      
      
        ;
        Throwable throwable 
      
      = 
      
        null
      
      
        ;
        StandardWrapper wrapper 
      
      =
      
         (StandardWrapper) getContainer();
        ServletRequest sreq 
      
      =
      
         request.getRequest();
        ServletResponse sres 
      
      =
      
         response.getResponse();
        Servlet servlet 
      
      = 
      
        null
      
      
        ;
        HttpServletRequest hreq 
      
      = 
      
        null
      
      
        ;
        
      
      
        if
      
       (sreq 
      
        instanceof
      
      
         HttpServletRequest)
            hreq 
      
      =
      
         (HttpServletRequest) sreq;
        HttpServletResponse hres 
      
      = 
      
        null
      
      
        ;
        
      
      
        if
      
       (sres 
      
        instanceof
      
      
         HttpServletResponse)
            hres 
      
      =
      
         (HttpServletResponse) sres;

        
      
      
        //
      
      
         Check for the application being marked unavailable
      
      
        if
      
       (!
      
        ((Context) wrapper.getParent()).getAvailable()) {
            hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                           sm.getString(
      
      "standardContext.isUnavailable"
      
        ));
            unavailable 
      
      = 
      
        true
      
      
        ;
        }

        
      
      
        //
      
      
         Check for the servlet being marked unavailable
      
      
        if
      
       (!unavailable &&
      
         wrapper.isUnavailable()) {
            log(sm.getString(
      
      "standardWrapper.isUnavailable"
      
        ,
                             wrapper.getName()));
            
      
      
        if
      
       (hres == 
      
        null
      
      
        ) {
                ;       
      
      
        //
      
      
         NOTE - Not much we can do generically
      
      
            } 
      
        else
      
      
         {
                
      
      
        long
      
       available =
      
         wrapper.getAvailable();
                
      
      
        if
      
       ((available > 0L) && (available <
      
         Long.MAX_VALUE))
                    hres.setDateHeader(
      
      "Retry-After"
      
        , available);
                hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                               sm.getString(
      
      "standardWrapper.isUnavailable"
      
        ,
                                            wrapper.getName()));
            }
            unavailable 
      
      = 
      
        true
      
      
        ;
        }

        
      
      
        //
      
      
         Allocate a servlet instance to process this request
      
      
        try
      
      
         {
            
      
      
        if
      
       (!
      
        unavailable) {
                servlet 
      
      =
      
         wrapper.allocate();
            }
        } 
      
      
        catch
      
      
         (ServletException e) {
            log(sm.getString(
      
      "standardWrapper.allocateException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
            servlet 
      
      = 
      
        null
      
      
        ;
        } 
      
      
        catch
      
      
         (Throwable e) {
            log(sm.getString(
      
      "standardWrapper.allocateException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
            servlet 
      
      = 
      
        null
      
      
        ;
        }

        
      
      
        //
      
      
         Acknowlege the request
      
      
        try
      
      
         {
            response.sendAcknowledgement();
        } 
      
      
        catch
      
      
         (IOException e) {
            sreq.removeAttribute(Globals.JSP_FILE_ATTR);
            log(sm.getString(
      
      "standardWrapper.acknowledgeException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
        } 
      
      
        catch
      
      
         (Throwable e) {
            log(sm.getString(
      
      "standardWrapper.acknowledgeException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
            servlet 
      
      = 
      
        null
      
      
        ;
        }

        
      
      
        //
      
      
         Create the filter chain for this request
      
      
        ApplicationFilterChain filterChain =
      
        
            createFilterChain(request, servlet);

        
      
      
        //
      
      
         Call the filter chain for this request
        
      
      
        //
      
      
         NOTE: This also calls the servlet's service() method
      
      
        try
      
      
         {
            String jspFile 
      
      =
      
         wrapper.getJspFile();
            
      
      
        if
      
       (jspFile != 
      
        null
      
      
        )
                sreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
            
      
      
        else
      
      
        
                sreq.removeAttribute(Globals.JSP_FILE_ATTR);
            
      
      
        if
      
       ((servlet != 
      
        null
      
      ) && (filterChain != 
      
        null
      
      
        )) {
                filterChain.doFilter(sreq, sres);
            }
            sreq.removeAttribute(Globals.JSP_FILE_ATTR);
        } 
      
      
        catch
      
      
         (IOException e) {
            sreq.removeAttribute(Globals.JSP_FILE_ATTR);
            log(sm.getString(
      
      "standardWrapper.serviceException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
        } 
      
      
        catch
      
      
         (UnavailableException e) {
            sreq.removeAttribute(Globals.JSP_FILE_ATTR);
            log(sm.getString(
      
      "standardWrapper.serviceException"
      
        ,
                             wrapper.getName()), e);
            
      
      
        //
      
      
                    throwable = e;
            
      
      
        //
      
      
                    exception(request, response, e);
      
      
                    wrapper.unavailable(e);
            
      
      
        long
      
       available =
      
         wrapper.getAvailable();
            
      
      
        if
      
       ((available > 0L) && (available <
      
         Long.MAX_VALUE))
                hres.setDateHeader(
      
      "Retry-After"
      
        , available);
            hres.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                           sm.getString(
      
      "standardWrapper.isUnavailable"
      
        ,
                                        wrapper.getName()));
            
      
      
        //
      
      
         Do not save exception in 'throwable', because we
            
      
      
        //
      
      
         do not want to do exception(request, response, e) processing
      
      
        } 
      
        catch
      
      
         (ServletException e) {
            sreq.removeAttribute(Globals.JSP_FILE_ATTR);
            log(sm.getString(
      
      "standardWrapper.serviceException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
        } 
      
      
        catch
      
      
         (Throwable e) {
            sreq.removeAttribute(Globals.JSP_FILE_ATTR);
            log(sm.getString(
      
      "standardWrapper.serviceException"
      
        ,
                             wrapper.getName()), e);
            throwable 
      
      =
      
         e;
            exception(request, response, e);
        }

        
      
      
        //
      
      
         Release the filter chain (if any) for this request
      
      
        try
      
      
         {
            
      
      
        if
      
       (filterChain != 
      
        null
      
      
        )
                filterChain.release();
        } 
      
      
        catch
      
      
         (Throwable e) {
            log(sm.getString(
      
      "standardWrapper.releaseFilters"
      
        ,
                             wrapper.getName()), e);
            
      
      
        if
      
       (throwable == 
      
        null
      
      
        ) {
                throwable 
      
      =
      
         e;
                exception(request, response, e);
            }
        }

        
      
      
        //
      
      
         Deallocate the allocated servlet instance
      
      
        try
      
      
         {
            
      
      
        if
      
       (servlet != 
      
        null
      
      
        ) {
                wrapper.deallocate(servlet);
            }
        } 
      
      
        catch
      
      
         (Throwable e) {
            log(sm.getString(
      
      "standardWrapper.deallocateException"
      
        ,
                             wrapper.getName()), e);
            
      
      
        if
      
       (throwable == 
      
        null
      
      
        ) {
                throwable 
      
      =
      
         e;
                exception(request, response, e);
            }
        }

        
      
      
        //
      
      
         If this servlet has been marked permanently unavailable,
        
      
      
        //
      
      
         unload it and release this instance
      
      
        try
      
      
         {
            
      
      
        if
      
       ((servlet != 
      
        null
      
      ) &&
      
        
                (wrapper.getAvailable() 
      
      ==
      
         Long.MAX_VALUE)) {
                wrapper.unload();
            }
        } 
      
      
        catch
      
      
         (Throwable e) {
            log(sm.getString(
      
      "standardWrapper.unloadException"
      
        ,
                             wrapper.getName()), e);
            
      
      
        if
      
       (throwable == 
      
        null
      
      
        ) {
                throwable 
      
      =
      
         e;
                exception(request, response, e);
            }
        }

    }
      
    

上述創(chuàng)建過濾器鏈的過程本人后來(lái)作了補(bǔ)充: How Tomcat Works(十四)補(bǔ)充

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

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

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

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

本文鏈接 http://www.cnblogs.com/chenying99/p/3242278.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ì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 康平县| 三门县| 汉源县| 河东区| 姚安县| 元朗区| 封丘县| 忻城县| 贡觉县| 达拉特旗| 丹巴县| 柳江县| 汶上县| 财经| 隆德县| 遂川县| 新营市| 咸宁市| 太保市| 吴桥县| 周口市| 鹤峰县| 丹巴县| 乡城县| 凉城县| 全椒县| 拉孜县| 阿拉尔市| 北安市| 清丰县| 荣成市| 平潭县| 锡林郭勒盟| 柘荣县| 休宁县| 玛曲县| 阿瓦提县| 宣汉县| 萍乡市| 永靖县| 竹溪县|