SpringMVC 拦截器源码解析

前言:这两天学习了代理模式,自然想到了SpringMVC 的 AOP 使用的就是动态代理,拦截器使用的就是 jdk 的动态代理。今天看了看源码,记录一下。SpringMVC 的拦截器使用移步:Java Servlet 过滤器与 SpringMVC 拦截器的区别?

源码解析

  springMVC 的所有连接入口都会进入 DispatcherServlet,然后在这里面去调用真正的 Controller。而拦截器要达到的作用则是在调用 Controller 前后去做一些事情。所以现在需要看看 DispatcherServlet 的源码。

DispatcherServlet

  DispatcherServlet 的源码入口在 doService() 方法。

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if(this.logger.isDebugEnabled()) {
            String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult()?" resumed":"";
            this.logger.debug("DispatcherServlet with name '" + this.getServletName() + "'" + resumed + " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
        }

Map<String, Object> attributesSnapshot = null;
        if(WebUtils.isIncludeRequest(request)) {
            attributesSnapshot = new HashMap();
            Enumeration attrNames = request.getAttributeNames();

label108:
            while(true) {
                String attrName;
                do {
                    if(!attrNames.hasMoreElements()) {
                        break label108;
                    }

attrName = (String)attrNames.nextElement();
                } while(!this.cleanupAfterInclude && !attrName.startsWith("org.springframework.web.servlet"));

attributesSnapshot.put(attrName, request.getAttribute(attrName));
            }
        }

request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext());
        request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
        request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
        request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource());
        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 {
            this.doDispatch(request, response);
        } finally {
            if(!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
                this.restoreAttributesAfterInclude(request, attributesSnapshot);
            }

}

}

  doService() 方法里面处理了一些信息之后,调用了 doDispatch() 方法。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {
            try {
                ModelAndView mv = null;
                Object dispatchException = null;

try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest);
                    if(mappedHandler == null || mappedHandler.getHandler() == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1020dbbf7e2db1bd408536c5967a6ba3.html