Tomcat请求源码流程分析(图解及源码注释) (六)

Tomcat源码系列:


本章为Tomcat请求解析流程的第二章,主要内容为在请求转交给Coyote适配器后的流程分析

紧接上文中请求交由Processor处理.

Tomcat初始化源码不适用于新手

文章内容只有部分流程的源码分析,通过代码注释的方法,仅适用于Tomcat的源码有一定的了解的同学.

目录

1.AbstractProcessorLight.process()

2. CoyoteAdapter.service()

3. Valve.inkove()

    3.1 StandardEngineValve.invoke()

    3.2 StandardHostValve.invoke()

    3.3  StandardContextValve.invoke()

    3.4 StandardWrapperValve.invoke()

4.wrapper.allocate()  构造Servlet实例

5. filterChain.doFilter(request.getRequest(),response.getResponse())

5.1 internalDoFilter(request,response);

5.2 servlet.service(request, response);

6.HttpServlet.service()

7.正式执行自定义Servlet.


1.AbstractProcessorLight.process()

当请求由Endpoint交由Processor处理时,首先经过的就是AbstractProcessorLight.process()

 public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status)
            throws IOException {

        SocketState state = SocketState.CLOSED;
        Iterator<DispatchType> dispatches = null;
        do {
            if (dispatches != null) {
                DispatchType nextDispatch = dispatches.next();
                if (getLog().isDebugEnabled()) {
                    getLog().debug("Processing dispatch type: [" + nextDispatch + "]");
                }
                state = dispatch(nextDispatch.getSocketStatus());
                if (!dispatches.hasNext()) {
                    state = checkForPipelinedData(state, socketWrapper);
                }
            } else if (status == SocketEvent.DISCONNECT) {
            } else if (isAsync() || isUpgrade() || state == SocketState.ASYNC_END) {
                state = dispatch(status);
                state = checkForPipelinedData(state, socketWrapper);
            } else if (status == SocketEvent.OPEN_WRITE) {
                // Extra write event likely after async, ignore
                state = SocketState.LONG;
            } else if (status == SocketEvent.OPEN_READ) {
                //调度Http11Processor.service方法
                state = service(socketWrapper);
            } else if (status == SocketEvent.CONNECT_FAIL) {
                logAccess(socketWrapper);
            } else {
                state = SocketState.CLOSED;
            }

            ....
            }
        } while (state == SocketState.ASYNC_END ||
                dispatches != null && state != SocketState.CLOSED);

        return state;
    }

2. CoyoteAdapter.service()

此时在service方法中会调用CoyoteAdapter.service(),至此请求就即将被发送给Engine引擎.

 //获取Coyote适配器,并调用其service方法
getAdapter().service(request, response);

3. Valve.inkove()

    3.1 StandardEngineValve.invoke()

在Coyote适配器中,会获取Engine容器的第一个Valve,即StandardEngineValve,并执行.

// 获取容器的第一个Valve执行
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

    3.2 StandardHostValve.invoke()

接下来依次调用host,context,wrapper的valve并执行.

host.getPipeline().getFirst().invoke(request, response);

    3.3  StandardContextValve.invoke()

context.getPipeline().getFirst().invoke(request, response);

    3.4 StandardWrapperValve.invoke()

wrapper.getPipeline().getFirst().invoke(request, response);

4.wrapper.allocate()  构造Servlet实例

当请求来到StandardWrapperValve时,首先会先实例化Servlet.

if (!unavailable) {
   servlet = wrapper.allocate();
   }

5. filterChain.doFilter(request.getRequest(),response.getResponse())

然后会开始构建Filter过滤器链.并执行过滤器链

//构造过滤器链
ApplicationFilterChain filterChain =
                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
        try {
            if ((servlet != null) && (filterChain != null)) {
                // Swallow output if needed
                if (context.getSwallowOutput()) {
                    try {
                        SystemLogHandler.startCapture();
                        if (request.isAsyncDispatching()) {
                            request.getAsyncContextInternal().doInternalDispatch();
                        } else {
                            //执行Filter
                            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 {
                        filterChain.doFilter
                            (request.getRequest(), response.getResponse());
                    }
                }

            }
        }

5.1 internalDoFilter(request,response);

当我们跟踪进doFilter方法,其中会调用internalDoFilter(request,response)方法

 internalDoFilter(request,response);

5.2 servlet.service(request, response);

在这个方法中会获取到Servlet实例,并调用service方法.

servlet.service(request, response);

6.HttpServlet.service()

我们知道我们用户自定义的Servlet实际上都是继承了HttpServlet方法,那么我们跟踪到HttpServlet.service()

@Override
    public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {

        HttpServletRequest  request;
        HttpServletResponse response;

        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException(lStrings.getString("http.non_http"));
        }
        service(request, response);
    }

 7.正式执行自定义Servlet.

在转换完Response和Request后,service会调用重载的service方法,此时则开始正式执行Get,Post等等.

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    // Invalid date header - proceed as if none was set
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);

        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);

        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);

        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);

        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);

        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);

            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }

至此Tomcat请求过程就正式结束了.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值