spring boot 与Tomcat结合

首先会执行ApplicationFilterChain的internalDoFilter方法

 1 private void internalDoFilter(ServletRequest request,
 2                               ServletResponse response)
 3     throws IOException, ServletException {
 4 
 5     // Call the next filter if there is one
 6     if (pos < n) {
 7         ApplicationFilterConfig filterConfig = filters[pos++];
 8         try {
 9             Filter filter = filterConfig.getFilter();
10 
11             if (request.isAsyncSupported() && "false".equalsIgnoreCase(
12                     filterConfig.getFilterDef().getAsyncSupported())) {
13                 request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE);
14             }
15             if( Globals.IS_SECURITY_ENABLED ) {
16                 final ServletRequest req = request;
17                 final ServletResponse res = response;
18                 Principal principal =
19                     ((HttpServletRequest) req).getUserPrincipal();
20 
21                 Object[] args = new Object[]{req, res, this};
22                 SecurityUtil.doAsPrivilege ("doFilter", filter, classType, args, principal);
23             } else {
24                 filter.doFilter(request, response, this);
25             }
26         } catch (IOException | ServletException | RuntimeException e) {
27             throw e;
28         } catch (Throwable e) {
29             e = ExceptionUtils.unwrapInvocationTargetException(e);
30             ExceptionUtils.handleThrowable(e);
31             throw new ServletException(sm.getString("filterChain.filter"), e);
32         }
33         return;
34     }
35 
36     // We fell off the end of the chain -- call the servlet instance
37     try {
38         if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
39             lastServicedRequest.set(request);
40             lastServicedResponse.set(response);
41         }
42 
43         if (request.isAsyncSupported() && !servletSupportsAsync) {
44             request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
45                     Boolean.FALSE);
46         }
47         // Use potentially wrapped request from this point
48         if ((request instanceof HttpServletRequest) &&
49                 (response instanceof HttpServletResponse) &&
50                 Globals.IS_SECURITY_ENABLED ) {
51             final ServletRequest req = request;
52             final ServletResponse res = response;
53             Principal principal =
54                 ((HttpServletRequest) req).getUserPrincipal();
55             Object[] args = new Object[]{req, res};
56             SecurityUtil.doAsPrivilege("service",
57                                        servlet,
58                                        classTypeUsedInService,
59                                        args,
60                                        principal);
61         } else {
62             servlet.service(request, response);
63         }
64     } catch (IOException | ServletException | RuntimeException e) {
65         throw e;
66     } catch (Throwable e) {
67         e = ExceptionUtils.unwrapInvocationTargetException(e);
68         ExceptionUtils.handleThrowable(e);
69         throw new ServletException(sm.getString("filterChain.servlet"), e);
70     } finally {
71         if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
72             lastServicedRequest.set(null);
73             lastServicedResponse.set(null);
74         }
75     }
76 }

关于ApplicationFilterChain内容,参考以下链接

https://blog.csdn.net/wanxu12345678910/article/details/83418344

https://blog.csdn.net/wanxu12345678910/article/details/83352371?spm=1001.2014.3001.5501

 

 

 这个servlet实例其实是DispatcherServlet,其service方法是调用DispatcherServlet父类的FrameworkServlet的service();

 1     @Override
 2     protected void service(HttpServletRequest request, HttpServletResponse response)
 3             throws ServletException, IOException {
 4 
 5         HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
 6         if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
 7             processRequest(request, response);
 8         }
 9         else {
10             super.service(request, response);
11         }
12     }

而service()方法又会调用其父类HttpServlet的service()方法;

 1     protected void service(HttpServletRequest req, HttpServletResponse resp)
 2         throws ServletException, IOException {
 3 
 4         String method = req.getMethod();
 5 
 6         if (method.equals(METHOD_GET)) {
 7             long lastModified = getLastModified(req);
 8             if (lastModified == -1) {
 9                 // servlet doesn't support if-modified-since, no reason
10                 // to go through further expensive logic
11                 doGet(req, resp);
12             } else {
13                 long ifModifiedSince;
14                 try {
15                     ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
16                 } catch (IllegalArgumentException iae) {
17                     // Invalid date header - proceed as if none was set
18                     ifModifiedSince = -1;
19                 }
20                 if (ifModifiedSince < (lastModified / 1000 * 1000)) {
21                     // If the servlet mod time is later, call doGet()
22                     // Round down to the nearest second for a proper compare
23                     // A ifModifiedSince of -1 will always be less
24                     maybeSetLastModified(resp, lastModified);
25                     doGet(req, resp);
26                 } else {
27                     resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
28                 }
29             }
30 
31         } else if (method.equals(METHOD_HEAD)) {
32             long lastModified = getLastModified(req);
33             maybeSetLastModified(resp, lastModified);
34             doHead(req, resp);
35 
36         } else if (method.equals(METHOD_POST)) {
37             doPost(req, resp);
38 
39         } else if (method.equals(METHOD_PUT)) {
40             doPut(req, resp);
41 
42         } else if (method.equals(METHOD_DELETE)) {
43             doDelete(req, resp);
44 
45         } else if (method.equals(METHOD_OPTIONS)) {
46             doOptions(req,resp);
47 
48         } else if (method.equals(METHOD_TRACE)) {
49             doTrace(req,resp);
50 
51         } else {
52             //
53             // Note that this means NO servlet supports whatever
54             // method was requested, anywhere on this server.
55             //
56 
57             String errMsg = lStrings.getString("http.method_not_implemented");
58             Object[] errArgs = new Object[1];
59             errArgs[0] = method;
60             errMsg = MessageFormat.format(errMsg, errArgs);
61 
62             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
63         }
64     }

 

 

 以上图片是FrameworkServlet继承关系

HttpServlet的doGet()又会调用FrameworkServlet实现的doGet()方法

    @Override
    protected final void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        processRequest(request, response);
    }

方法内又会调用FrameworkServlet的processRequest()

protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        long startTime = System.currentTimeMillis();
        Throwable failureCause = null;

        LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
        LocaleContext localeContext = buildLocaleContext(request);

        RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
        asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

        initContextHolders(request, localeContext, requestAttributes);

        try {
            doService(request, response);
        }
        catch (ServletException | IOException ex) {
            failureCause = ex;
            throw ex;
        }
        catch (Throwable ex) {
            failureCause = ex;
            throw new NestedServletException("Request processing failed", ex);
        }

        finally {
            resetContextHolders(request, previousLocaleContext, previousAttributes);
            if (requestAttributes != null) {
                requestAttributes.requestCompleted();
            }
            logResult(request, response, failureCause, asyncManager);
            publishRequestHandledEvent(request, response, startTime, failureCause);
        }
    }

最后调用子类DispatcherServlet的doService()

@Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logRequest(request);

        // Keep a snapshot of the request attributes in case of an include,
        // to be able to restore the original attributes after the include.
        Map<String, Object> attributesSnapshot = null;
        if (WebUtils.isIncludeRequest(request)) {
            attributesSnapshot = new HashMap<>();
            Enumeration<?> attrNames = request.getAttributeNames();
            while (attrNames.hasMoreElements()) {
                String attrName = (String) attrNames.nextElement();
                if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
                    attributesSnapshot.put(attrName, request.getAttribute(attrName));
                }
            }
        }

        // Make framework objects available to handlers and view objects.
        request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
        request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
        request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
        request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());

        if (this.flashMapManager != null) {
            FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
            if (inputFlashMap != null) {
                request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
            }
            request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
            request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
        }

        try {
            doDispatch(request, response);
        }
        finally {
            if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
                // Restore the original attribute snapshot, in case of an include.
                if (attributesSnapshot != null) {
                    restoreAttributesAfterInclude(request, attributesSnapshot);
                }
            }
        }
    }

方法内便会调用Spring Mvc最重要的方法doDispatch(),该方法会会执行请求处理操作,包括请求分发,响应处理等核心操作

 1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
 2         HttpServletRequest processedRequest = request;
 3         HandlerExecutionChain mappedHandler = null;
 4         boolean multipartRequestParsed = false;
 5 
 6         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
 7 
 8         try {
 9             ModelAndView mv = null;
10             Exception dispatchException = null;
11 
12             try {
13                 processedRequest = checkMultipart(request);
14                 multipartRequestParsed = (processedRequest != request);
15 
16                 // Determine handler for the current request.
17                 mappedHandler = getHandler(processedRequest);
18                 if (mappedHandler == null) {
19                     noHandlerFound(processedRequest, response);
20                     return;
21                 }
22 
23                 // Determine handler adapter for the current request.
24                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
25 
26                 // Process last-modified header, if supported by the handler.
27                 String method = request.getMethod();
28                 boolean isGet = "GET".equals(method);
29                 if (isGet || "HEAD".equals(method)) {
30                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
31                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
32                         return;
33                     }
34                 }
35 
36                 if (!mappedHandler.applyPreHandle(processedRequest, response)) {
37                     return;
38                 }
39 
40                 // Actually invoke the handler.
41                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
42 
43                 if (asyncManager.isConcurrentHandlingStarted()) {
44                     return;
45                 }
46 
47                 applyDefaultViewName(processedRequest, mv);
48                 mappedHandler.applyPostHandle(processedRequest, response, mv);
49             }
50             catch (Exception ex) {
51                 dispatchException = ex;
52             }
53             catch (Throwable err) {
54                 // As of 4.3, we're processing Errors thrown from handler methods as well,
55                 // making them available for @ExceptionHandler methods and other scenarios.
56                 dispatchException = new NestedServletException("Handler dispatch failed", err);
57             }
58             processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
59         }
60         catch (Exception ex) {
61             triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
62         }
63         catch (Throwable err) {
64             triggerAfterCompletion(processedRequest, response, mappedHandler,
65                     new NestedServletException("Handler processing failed", err));
66         }
67         finally {
68             if (asyncManager.isConcurrentHandlingStarted()) {
69                 // Instead of postHandle and afterCompletion
70                 if (mappedHandler != null) {
71                     mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
72                 }
73             }
74             else {
75                 // Clean up any resources used by a multipart request.
76                 if (multipartRequestParsed) {
77                     cleanupMultipart(processedRequest);
78                 }
79             }
80         }
81     }

 

posted @ 2021-06-07 10:43  Joseph_David  阅读(1)  评论(0)    收藏  举报