从DispatcherServlet开始到结束,浅谈springmvc执行流程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wjw521wjw521/article/details/101100340

这篇文章,DispatcherServlet是个重点,谈springmvc绕不开他,我们使用他作为springmvc接管web项目request的入口(在web.xml)中配置。

所以,接下来,将这位老大哥的身子贴在下面,请大家文明阅览:

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;
                Exception 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;
                    }

                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }

                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var19) {
                    dispatchException = var19;
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
            } catch (Exception var20) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
            } catch (Error var21) {
                this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

理解springmvc的执行流程,不会让你瞬间理解整个springmvc框架所有高级用法,因为这种水平是经验的积累,但是却能大大加快这个进程,理解springmvc相当于牵到的马鼻子,驯服烈马也就简单了些,闲言少叙,进入正题。

springmvc中有几个重要角色,我在这里列一下:

request:不只springmvc,所有的web请求都是从他开始,您的鼠标轻轻一点,request寄托着您的思念来到了我家的服务器端口前,准备破口而入。

HandlerExecutionChain:处理器拦截器链,springmvc对request的映射

HandlerAdapter:处理器适配器(适配器模式)

接下来简单描述一下springmvc的处理流程:

我们web容器启动,监听http接口(大多数为80),一个request到达,查看web.xml文件,发现配置了url-pattern将请求处理接手,这个接手处理的servlet就是DispatcherServlet,该servlet的核心方法是是doDispatch,在javaweb一个request初始被封装为HttpServletRequest。

我们在使用springmvc过程中,一般会配置映射(显示的或隐式的使用注解驱动)来找到我们的页面控制器,也就是我们常说的Controller,有些需求我们还要配置拦截器(比如登陆权限验证等),springmvc就将我们的request通过handlerMapping映射成为一个执行器链HandlerExecutionChain,也就是我们的request将来就要在这个执行器链中走一遭。

然后为了统一handler接口(也就是我们的Controller),springmvc将我们自己写的Controller包装成了handlerAdapter(适配器模式),这时候你要是不认识自己写的页面处理器(controller),handlerAdapter就会和你说:兄嘚,我穿上马甲你就不认识我了。

接下来真正处理request,先执行拦截器接口中的preHandler方法,再执行ha(handlerAdapter)中的handle方法,执行完handle方法,再执行拦截器接口的posthandle

public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

    void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;

    void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}

接下来根据我们ha.handle返回的ModelAndView进行视图解析,返回前端,如果这样说太笼统,这个怎么理解呢,过程如下:

我们现在执行完handle(你可以看成执行完你自己写的Controller中的requestMapping方法),手握ModelAndView,我们手中现在既有Model模型数据,也有View视图数据,但我们现在手里握着的视图数据是抽象的,还没有落实到我们真正的jsp页面、velocity模板页面、freemarker页面或其他模板页面中,我们现在就握着个抽象view有什么用?用处大啦!我们可以根据我们的需要,选择不同的视图解析器将其落实到真正的真正的jsp页面、velocity模板页面、freemarker页面上,至于选哪个?自己配置视图解析器去。

好,我们落实了view,接下来落实Model,数据在手,天下我有,View有了实处,Model自然也找到落脚点,进行数据填充,返回前端。

流程基本结束。

匆忙间写就,如有错误,欢迎指正。

猜你喜欢

转载自blog.csdn.net/wjw521wjw521/article/details/101100340
今日推荐