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

How Tomcat Works(十四)

系統 1839 0

我們已經知道,在tomcat中有四種類型的servlet容器,分別為Engine、Host、Context 和Wrapper,本文接下來對tomcat中Wrapper接口的標準實現進行說明。

對于每個引入的HTTP請求,連接器都會調用與其關聯的servlet容器的invoke()方法;然后,servlet容器會調用所有子容器的invoke()方法

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

在tomcat中,servlet類可以實現javax.servlet.SingleThreadModel接口,這樣的servlet類也稱為SingleThreadModel(STM)servlet類;根據Servlet規(guī)范,實現此接口的目的是保證servlet實例一次只處理一個請求。

StandardWrapper對象的主要任務是載入它所代表的servlet類,并進行實例化;不過StandardWrapper類并不調用servlet的service方法,該任務由StandardWrapperValve對象(StandardWrapper實例的管道對象中的基礎閥)完成;StandardWrapperValve對象通過調用StandardWrapper實例的allocate()方法獲取servlet實例,在獲取實例后,StandardWrapperValve實例就會調用servlet實例的service()方法

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

而對于STM 類型的servlet類,StandardWrapper實例必須保證每一時刻只能有一個線程在執(zhí)行STM servlet類的service()方法;StandardWrapper實例通過將STM 類型的servlet實例保存在一個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類,然后實例化該servlet類,最后調用該servlet實例的init()方法初始化(傳入javax.servlet.ServletConfig對象)

      
        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類后,會調用該servlet實例的init()方法,該方法需要傳入一個javax.servlet.ServletConfig實例作為參數;那么,?StandardWrapper對象是如何獲取ServletConfig對象的呢

答案就在StandardWrapper類本身,該類不僅實現了Wrapper接口,還實現了javax.servlet.ServletConfig接口,下面是相關方法實現

      
        /**
      
      
        
     * 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實例在它的loadServlet()方法里面調用它所載入的servlet類的實例的init()方法,該方法需要一個javax.servlet.ServletConfig類型參數,理論上StandardWrapper對象可以將自身傳入init()方法,不過為了類型安全,StandardWrapper類將自身實例包裝成StandardWrapperFacade類的一個實例,然后再傳給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實例中的基礎閥,要完成兩個操作

(1)執(zhí)行與該servlet相關聯的全部過濾器

(2)調用servlet實例的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)建過濾器鏈的過程本人后來作了補充: How Tomcat Works(十四)補充

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

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

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

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

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

How Tomcat Works(十四)


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲精品第一国产综合高清 | 国产精品视频免费在线观看 | 精品国产区一区二区三区在线观看 | 毛片大片免费看 | 久久精品观看影院2828 | 日韩欧美在线观看视频 | www操操 | 国产成人aa在线观看视频 | 日韩中文字幕精品视频在线 | 久久综合精品国产一区二区三区无 | 国产精品日韩欧美一区二区 | 国产成人久久久精品毛片 | 免费可以直接观看的毛片 | 亚洲视频在线观看 | 在线欧美亚洲 | 99久久免费精品国产免费高清 | 国内在线播放 | 香蕉视频免费在线 | 国产欧美精品一区二区三区–老狼 | 在线观看日韩视频 | 在线播放日韩 | 久久99热精品免费观看无卡顿 | 亚洲视频污| 国产一区二区精品久 | 欧美成人性做爰 | 国产一区二区在线不卡 | 亚洲综合色秘密影院秘密影院 | 最新国产福利 | 天天综合在线视频 | 奇米影视亚洲春色77777 | 香蕉尹人综合精品 | 91在线成人 | 亚洲男人天堂视频 | 一区二区三区在线 | 网站 | 狠狠色丁香婷婷久久综合考虑 | 欧洲一区在线观看 | 日韩欧美第一区二区三区 | 久久精品美女久久 | 亚洲天堂资源 | 天堂一区二区三区在线观看 | 香蕉爱爱视频 |