wu_quanyin 发表于 2013-2-6 10:20:46

Tomcat源码---请求处理四(2)

对以上的StandardWrapperValve#invoke进行说解
 

[*]  if (!unavailable) {  
[*]                //servlet行行在这一步  
[*]                servlet = wrapper.allocate();  
[*]            }  
 
 
public Servlet allocate() throws ServletException {      // If we are currently unloading this servlet, throw an exception      if (unloading)            throw new ServletException            (sm.getString("standardWrapper.unloading", getName()));      boolean newInstance = false;                // 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 {                            if (log.isDebugEnabled())                              log.debug("Allocating non-STM instance");                            //创建实例                            instance = loadServlet();                            // For non-STM, increment here to prevent a race                            // condition with unload. Bug 43683, test case #3                            if (!singleThreadModel) {                              newInstance = true;                               //                              countAllocated.incrementAndGet();                            }                        } catch (ServletException e) {                            throw e;                        } catch (Throwable e) {                            throw new ServletException                              (sm.getString("standardWrapper.allocate"), e);                        }                  }                }            }            if (!singleThreadModel) {                if (log.isTraceEnabled())                  log.trace("Returning non-STM instance");                // For new instances, count will have been incremented at the                // time of creation                if (!newInstance) {                  countAllocated.incrementAndGet();                }                return (instance);            }      }      //每一次都返回一个实例存放在instancePool中      synchronized (instancePool) {            while (countAllocated.get() >= 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 (log.isTraceEnabled())                log.trace("Returning allocated STM instance");            countAllocated.incrementAndGet();            return (Servlet) instancePool.pop();      }    }   以上这一步在我们平时使用时会经常遇到,,servlet的创建是一个多线程单实例的,所以共享全局变量,所以在使用servlet
时应尽量避免定义全局变量
对#loadServlet进行详解
 
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;      if (swallowOutput) {            SystemLogHandler.startCapture();      }      Servlet servlet;      try {            long t1=System.currentTimeMillis();            // 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            //所访问的servlet的类路径名            String actualClass = servletClass;            if ((actualClass == null) && (jspFile != null)) {                Wrapper jspWrapper = (Wrapper)                  ((Context) getParent()).findChild(Constants.JSP_SERVLET_NAME);                if (jspWrapper != null) {                  actualClass = jspWrapper.getServletClass();                  // Merge init parameters                  String paramNames[] = jspWrapper.findInitParameters();                  for (int i = 0; i < paramNames.length; i++) {                        if (parameters.get(paramNames) == null) {                            parameters.put                              (paramNames,                                  jspWrapper.findInitParameter(paramNames));                        }                  }                }            }            // 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()));            }            //获取werbappclassloader            ClassLoader classLoader = loader.getClassLoader();            // Special case class loader for a container provided servlet            //            if (isContainerProvidedServlet(actualClass) &&                     ! ((Context)getParent()).getPrivileged() ) {                // If it is a priviledged context - using its own                // class loader will work, since it's a child of the container                // loader                classLoader = this.getClass().getClassLoader();            }            // Load the specified servlet class from the appropriate class loader            Class classClass = null;            try {                if (SecurityUtil.isPackageProtectionEnabled()){                  final ClassLoader fclassLoader = classLoader;                  final String factualClass = actualClass;                  try{                        classClass = (Class)AccessController.doPrivileged(                              new PrivilegedExceptionAction(){                                    public Object run() throws Exception{                                        if (fclassLoader != null) {                                          //进行类加载                                          return fclassLoader.loadClass(factualClass);                                        } else {                                          return Class.forName(factualClass);                                        }                                    }                        });                  } catch(PrivilegedActionException pax){                        Exception ex = pax.getException();                        if (ex instanceof ClassNotFoundException){                            throw (ClassNotFoundException)ex;                        } else {                            getServletContext().log( "Error loading "                              + fclassLoader + " " + factualClass, ex );                        }                  }                } else {                  if (classLoader != null) {                        classClass = classLoader.loadClass(actualClass);                  } else {                        classClass = Class.forName(actualClass);                  }                }            } catch (ClassNotFoundException e) {                unavailable(null);                getServletContext().log( "Error loading " + classLoader + " " + actualClass, e );                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();                // Annotation processing                if (!((Context) getParent()).getIgnoreAnnotations()) {                  if (getParent() instanceof StandardContext) {                     ((StandardContext)getParent()).getAnnotationProcessor().processAnnotations(servlet);                     ((StandardContext)getParent()).getAnnotationProcessor().postConstruct(servlet);                  }                }            } catch (ClassCastException e) {                unavailable(null);                // Restore the context ClassLoader                throw new ServletException                  (sm.getString("standardWrapper.notServlet", actualClass), e);            } catch (Throwable e) {                unavailable(null);                              // Added extra log statement for Bugzilla 36630:                // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630                if(log.isDebugEnabled()) {                  log.debug(sm.getString("standardWrapper.instantiate", actualClass), e);                }                // 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) ||                  ((Context)getParent()).getPrivileged() )) {                ((ContainerServlet) servlet).setWrapper(this);            }            classLoadTime=(int) (System.currentTimeMillis() -t1);            // Call the initialization method of this servlet         //该Servlet的初始化,只实现一次            try {                instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT,                                                servlet);                if( Globals.IS_SECURITY_ENABLED) {                  Object[] args = new Object[]{((ServletConfig)facade)};                  SecurityUtil.doAsPrivilege("init",                                             servlet,                                             classType,                                             args);                  args = null;                } else {                  servlet.init(facade);                }                // Invoke jspInit on JSP pages                //jsp转换成servlet的初始化                if ((loadOnStartup >= 0) && (jspFile != null)) {                  // Invoking jspInit                  DummyRequest req = new DummyRequest();                  req.setServletPath(jspFile);                  req.setQueryString(Constants.PRECOMPILE + "=true");                  DummyResponse res = new DummyResponse();                  if( Globals.IS_SECURITY_ENABLED) {                        Object[] args = new Object[]{req, res};                        SecurityUtil.doAsPrivilege("service",                                                   servlet,                                                   classTypeUsedInService,                                                   args);                        args = null;                  } else {                        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) {                getServletContext().log("StandardWrapper.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);            loadTime=System.currentTimeMillis() -t1;      } finally {            if (swallowOutput) {                String log = SystemLogHandler.stopCapture();                if (log != null && log.length() > 0) {                  if (getServletContext() != null) {                        getServletContext().log(log);                  } else {                        out.println(log);                  }                }            }      }      return servlet;    } 从以上步骤可得到该servlet的实例,并用已经初始化过
现在对StandardWrapperValve#invoke
 

[*]      //这里面开始对过滤器进行处理  
[*]                            filterChain.doFilter(request.getRequest(),   
[*]                                    response.getResponse()); 
 
这里面对过滤器进行了执行ApplicationFilterChain#doFilter
 
public void doFilter(ServletRequest request, ServletResponse response)      throws IOException, ServletException {      if( Globals.IS_SECURITY_ENABLED ) {            final ServletRequest req = request;            final ServletResponse res = response;            try {                java.security.AccessController.doPrivileged(                  new java.security.PrivilegedExceptionAction() {                        public Object run()                           throws ServletException, IOException {                            internalDoFilter(req,res);                            return null;                        }                  }                );            } catch( PrivilegedActionException pe) {                Exception e = pe.getException();                if (e instanceof ServletException)                  throw (ServletException) e;                else if (e instanceof IOException)                  throw (IOException) e;                else if (e instanceof RuntimeException)                  throw (RuntimeException) e;                else                  throw new ServletException(e.getMessage(), e);            }      } else {         //这一步才是真正的执行            internalDoFilter(request,response);      }    } #internalDoFilter(rquest,response)
 
private void internalDoFilter(ServletRequest request,                                 ServletResponse response)      throws IOException, ServletException {      // Call the next filter if there is one      if (pos < n) {            ApplicationFilterConfig filterConfig = filters;            Filter filter = null;            try {                //获取过滤器                filter = filterConfig.getFilter();                support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,                                          filter, request, response);                              if( Globals.IS_SECURITY_ENABLED ) {                  final ServletRequest req = request;                  final ServletResponse res = response;                  Principal principal =                         ((HttpServletRequest) req).getUserPrincipal();                  Object[] args = new Object[]{req, res, this};                  SecurityUtil.doAsPrivilege                        ("doFilter", filter, classType, args, principal);                                        args = null;                } else {                      //进行过滤                  filter.doFilter(request, response, this);                }                support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,                                          filter, request, response);            } catch (IOException e) {                if (filter != null)                  support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,                                              filter, request, response, e);                throw e;            } catch (ServletException e) {                if (filter != null)                  support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,                                              filter, request, response, e);                throw e;            } catch (RuntimeException e) {                if (filter != null)                  support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,                                              filter, request, response, e);                throw e;            } catch (Throwable e) {                if (filter != null)                  support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,                                              filter, request, response, e);                throw new ServletException                  (sm.getString("filterChain.filter"), e);            }            return;      }      // We fell off the end of the chain -- call the servlet instance      try {            if (Globals.STRICT_SERVLET_COMPLIANCE) {                lastServicedRequest.set(request);                lastServicedResponse.set(response);            }            support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,                                    servlet, request, response);            if ((request instanceof HttpServletRequest) &&                (response instanceof HttpServletResponse)) {                                    if( Globals.IS_SECURITY_ENABLED ) {                  final ServletRequest req = request;                  final ServletResponse res = response;                  Principal principal =                         ((HttpServletRequest) req).getUserPrincipal();                  Object[] args = new Object[]{req, res};                  SecurityUtil.doAsPrivilege("service",                                             servlet,                                             classTypeUsedInService,                                                args,                                             principal);                     args = null;                } else {                      servlet.service((HttpServletRequest) request,                                    (HttpServletResponse) response);                }            } else {                //有过滤器,先过滤再执行servlet的service的方法                servlet.service(request, response);            }            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,                                    servlet, request, response);      } catch (IOException e) {            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,                                    servlet, request, response, e);            throw e;      } catch (ServletException e) {            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,                                    servlet, request, response, e);            throw e;      } catch (RuntimeException e) {            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,                                    servlet, request, response, e);            throw e;      } catch (Throwable e) {            support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,                                    servlet, request, response, e);            throw new ServletException            (sm.getString("filterChain.servlet"), e);      } finally {            if (Globals.STRICT_SERVLET_COMPLIANCE) {                lastServicedRequest.set(null);                lastServicedResponse.set(null);            }      }    } 这样的过滤器已经执行,servlet也已经执行....接下来做些释放工程
页: [1]
查看完整版本: Tomcat源码---请求处理四(2)