1.SpringMVC之源码分析

HiddenHttpMethodFilter源码分析:

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {

    //获取表单上_method带来的值(delete/put)
    String paramValue = request.getParameter(this.methodParam);

    //判断如果表单是一个post而且_method有值
    if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {

        //转为PUT、DELETE
        String method = paramValue.toUpperCase(Locale.ENGLISH);

        //重写了request.getMethod()
        HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);

        //wrapper.getMethod()==PUT
        filterChain.doFilter(wrapper, response);
    }
    else {

        //直接放行
        filterChain.doFilter(request, response);
    }
}
 *   关系:
 *   	Map,Model,ModelMap 最终都是BindingAwareModelMap在工作
 *   	相当于给BindingAwareModelMap中保存的东西都会被放在请求域中
 * 
 * 		Map(interface(jdk))      Model(interface(spring))  
 * 			||							//
 * 			||						   //
 * 			\/						  //
 * 		ModelMap(class)			     //
 * 					\\				//
 * 					 \\	           //
 * 					 ExtendedModelMap
 * 							||
 * 							\/
 * 					 BindingAwareModelMap

DispatcherServlet执行过程源码分析:
前端控制器DispatcherServlet的架构:
在这里插入图片描述
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 {
        ModelAndView mv = null;
        Exception dispatchException = null;
        try {
            
            // 1、检查是否文件上传请求
            processedRequest = checkMultipart(request);
            multipartRequestParsed = processedRequest != request;
                
            // Determine handler for the current request.
            // 2、根据当前的请求地址找到哪个类能来处理
            mappedHandler = getHandler(processedRequest);


            // 3、如果没有找到哪个处理器(控制器)能处理这个请求就404,或者抛异常
            if (mappedHandler == null || mappedHandler.getHandler() == null) {
                noHandlerFound(processedRequest, response); //抛异常
                return;
            }


            // Determine handler adapter for the current request.
            // 4、拿到能执行这个类的所有方法的适配器
            // (反射工具AnnotationMethodHandlerAdapter)
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

            // Process last-modified header, if supported by the handler.
            String method = request.getMethod();
            boolean isGet = "GET".equals(method);
            if (isGet || "HEAD".equals(method)) {
                long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                if (logger.isDebugEnabled()) {
                    String requestUri = urlPathHelper.getRequestUri(request);
                    logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
                }
                if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                    return;
                }
            }
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }
            try {

                // Actually invoke the handler.处理(控制)器的方法被调用
                // 控制器(Controller),处理器(Handler)
                // 5、适配器来执行目标方法,将目标方法执行完成后的返回值作为视图名
                // 设置保存到ModelAndView中
                // 目标方法无论怎么写,最终适配器执行完成以后都会将执行后的信息封装成ModelAndView
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

            }
            finally {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
            }

                // 如果没有视图名设置一个默认的视图名
                applyDefaultViewName(request, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);

            }
            catch (Exception ex) {
                dispatchException = ex;
            }

            // 转发到目标页面
            // 6、根据方法最终执行完成后封装的ModelAndView;转发到对应页面,而且ModelAndView中的数据可以从请求域中获取
            // processedRequest:封住后的请求对象
            // response:相应对象
            // mappedHandler:处理器
            // mv:ModelAndView
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

        }
        catch (Exception ex) {
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Error err) {
            triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                // Instead of postHandle and afterCompletion
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                return;
            }
            // Clean up any resources used by a multipart request.
            if (multipartRequestParsed) {
                cleanupMultipart(processedRequest);
            }
        }
    }

总结:
1)、所有请求过来DispatcherServlet收到请求
2)、调用doDispatch()方法进行处理
1)、getHandler(): 根据当前请求地址找到能处理这个请求的目标处理器类(处理器)
根据当前请求在HandlerMapping中找到这个请求的映射信息,获取到目标处理器类
2)、getHandlerAdapter(): 根据当前处理器类获取到能执行这个处理器方法的适配器
根据当前处理器类,找到当前类的HandlerAdapter(适配器)
3)、使用刚才获取到的适配器(AnnotationMethodHandlerAdapter)执行目标方法
4)、目标方法执行后会返回一个ModelAndView对象
5)、根据ModelAndView的信息转发到具体的页面,并可以在请求域中取出ModelAndView模型中的数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值