Wrapper组件 - 969251639/study GitHub Wiki

Wrapper其实就是一个Servlet,到了这里也就是真正Servlet入口,继续接收从context流入进来的管道数据

final class StandardWrapperValve
    extends ValveBase {
    ...
    @Override
    public final void invoke(Request request, Response response)
        throws IOException, ServletException {
        ...
        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();//根据web.xml中的servletClass反射一个servlet对象出来
            }
        } 
        ...
        // Create the filter chain for this request
        ApplicationFilterChain filterChain =
                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);//获取过滤器链

        // Call the filter chain for this request
        // NOTE: This also calls the servlet's service() method
        try {
            if ((servlet != null) && (filterChain != null)) {
                // Swallow output if needed
                if (context.getSwallowOutput()) {
                    try {
                        SystemLogHandler.startCapture();
                        if (request.isAsyncDispatching()) {
                            request.getAsyncContextInternal().doInternalDispatch();
                        } else if (comet) {
                            filterChain.doFilterEvent(request.getEvent());
                        } else {
                            filterChain.doFilter(request.getRequest(),
                                    response.getResponse());
                        }
                    } finally {
                        String log = SystemLogHandler.stopCapture();
                        if (log != null && log.length() > 0) {
                            context.getLogger().info(log);
                        }
                    }
                } else {
                    if (request.isAsyncDispatching()) {
                        request.getAsyncContextInternal().doInternalDispatch();
                    } else if (comet) {
                        filterChain.doFilterEvent(request.getEvent());
                    } else {
                        filterChain.doFilter
                            (request.getRequest(), response.getResponse());
                    }
                }

            }
        } 
        ...
        // Deallocate the allocated servlet instance
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        }
        ...
    }
    ...
}

上面的invoke方法很长,看重点部分

  1. 创建Servlet
public class StandardWrapper extends ContainerBase
    implements ServletConfig, Wrapper, NotificationEmitter {
    @Override
    public Servlet allocate() throws ServletException {
        ...
                            instance = loadServlet();
        ...
                    if (!instanceInitialized) {
                        initServlet(instance);
                    }
                }
            }
         ...
    }

    public synchronized Servlet loadServlet() throws ServletException {
        ...
        Servlet servlet;
        ...
            InstanceManager instanceManager = ((StandardContext)getParent()).getInstanceManager();
        ...
                servlet = (Servlet) instanceManager.newInstance(servletClass);
        ...
            initServlet(servlet);
        ...
        return servlet;
    }
    private synchronized void initServlet(Servlet servlet)
            throws ServletException {
        ....
        servlet.init(facade);
        ....
        instanceInitialized = true;
    }
}
  1. 获取可以拦截该servlet的过滤器链
public final class ApplicationFilterFactory {
    ...
    @SuppressWarnings("deprecation")
    public static ApplicationFilterChain createFilterChain
        (ServletRequest request, Wrapper wrapper, Servlet servlet) {

        // get the dispatcher type
        DispatcherType dispatcher = null;
        if (request.getAttribute(Globals.DISPATCHER_TYPE_ATTR) != null) {
            dispatcher = (DispatcherType) request.getAttribute(
                    Globals.DISPATCHER_TYPE_ATTR);
        }
        String requestPath = null;
        Object attribute = request.getAttribute(
                Globals.DISPATCHER_REQUEST_PATH_ATTR);

        if (attribute != null){
            requestPath = attribute.toString();
        }

        // If there is no servlet to execute, return null
        if (servlet == null)
            return (null);

        boolean comet = false;

        // Create and initialize a filter chain object
        ApplicationFilterChain filterChain = null;
        if (request instanceof Request) {
            Request req = (Request) request;
            comet = req.isComet();
            if (Globals.IS_SECURITY_ENABLED) {
                // Security: Do not recycle
                filterChain = new ApplicationFilterChain();
                if (comet) {
                    req.setFilterChain(filterChain);
                }
            } else {
                filterChain = (ApplicationFilterChain) req.getFilterChain();
                if (filterChain == null) {
                    filterChain = new ApplicationFilterChain();
                    req.setFilterChain(filterChain);
                }
            }
        } else {
            // Request dispatcher in use
            filterChain = new ApplicationFilterChain();
        }

        filterChain.setServlet(servlet);

        filterChain.setSupport
            (((StandardWrapper)wrapper).getInstanceSupport());

        // Acquire the filter mappings for this Context
        StandardContext context = (StandardContext) wrapper.getParent();
        FilterMap filterMaps[] = context.findFilterMaps();

        // If there are no filter mappings, we are done
        if ((filterMaps == null) || (filterMaps.length == 0))
            return (filterChain);

        // Acquire the information we will need to match filter mappings
        String servletName = wrapper.getName();

        // Add the relevant path-mapped filters to this filter chain
        // 匹配过滤器
        for (int i = 0; i < filterMaps.length; i++) {
            if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
                continue;
            }
            if (!matchFiltersURL(filterMaps[i], requestPath))//是否匹配拦截
                continue;
            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                context.findFilterConfig(filterMaps[i].getFilterName());
            if (filterConfig == null) {
                // FIXME - log configuration problem
                continue;
            }
            boolean isCometFilter = false;
            if (comet) {
                try {
                    isCometFilter = filterConfig.getFilter() instanceof CometFilter;
                } catch (Exception e) {
                    // Note: The try catch is there because getFilter has a lot of
                    // declared exceptions. However, the filter is allocated much
                    // earlier
                    Throwable t = ExceptionUtils.unwrapInvocationTargetException(e);
                    ExceptionUtils.handleThrowable(t);
                }
                if (isCometFilter) {
                    filterChain.addFilter(filterConfig);
                }
            } else {
                filterChain.addFilter(filterConfig);
            }
        }

        // 匹配servlet
        // Add filters that match on servlet name second
        for (int i = 0; i < filterMaps.length; i++) {
            if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
                continue;
            }
            if (!matchFiltersServlet(filterMaps[i], servletName))//根据servlet name匹配
                continue;
            ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                context.findFilterConfig(filterMaps[i].getFilterName());
            if (filterConfig == null) {
                // FIXME - log configuration problem
                continue;
            }
            boolean isCometFilter = false;
            if (comet) {
                try {
                    isCometFilter = filterConfig.getFilter() instanceof CometFilter;
                } catch (Exception e) {
                    // Note: The try catch is there because getFilter has a lot of
                    // declared exceptions. However, the filter is allocated much
                    // earlier
                }
                if (isCometFilter) {
                    filterChain.addFilter(filterConfig);
                }
            } else {
                filterChain.addFilter(filterConfig);
            }
        }

        // Return the completed filter chain
        return (filterChain);

    }
    ...
}
  1. 调用过滤器链,同时也调用Servlet的service方法执行servlet逻辑
final class ApplicationFilterChain implements FilterChain, CometFilterChain {
    ...
    @Override
    public void doFilter(ServletRequest request, ServletResponse response)
        throws IOException, ServletException {
        ...
            internalDoFilter(request,response);
        ...
    }
    private void internalDoFilter(ServletRequest request,
                                  ServletResponse response)
        throws IOException, ServletException {

        // Call the next filter if there is one
        if (pos < n) {//true执行filter,否则执行servlet
            ApplicationFilterConfig filterConfig = filters[pos++];
            Filter filter = null;
            ...
                filter = filterConfig.getFilter();
            ...

                    filter.doFilter(request, response, this);//调用下一个filter
            ...
            return;
        }
        ...
                    servlet.service(request, response);//调用Servlet的service方法
        ...
    }
    ...    
}