HandlerAdapter工作流程,运行原理
HandlerAdapter是处理适配器,它调用具体的方法对用户发来的请求来进行处理。SpringMVC 通过HandlerAdapter的handler方法来调用请求处理函数,它的工作运行原理如下。
工作流程概述
1.DispatcherServlte会根据配置文件信息注册HandlerAdapter,如果在配置文件中没有配置,那么 DispatcherServlte会获取HandlerAdapter的默认配置,如果是读取默认配置的话,DispatcherServlte会读取 DispatcherServlte.properties文件,该文件中配置了三种 HandlerAdapter:HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和 AnnotationMethodHandlerAdapter。DispatcherServlte会将这三个HandlerAdapter对象存储到 它的handlerAdapters这个集合属性中,这样就完成了HandlerAdapter的注册。
2.DispatcherServlte会根据handlerMapping传过来的controller与已经注册好了的HandlerAdapter 一一匹配,看哪一种HandlerAdapter是支持该controller类型的,如果找到了其中一种HandlerAdapter是支持传过来的 controller类型,那么该HandlerAdapter会调用自己的handle方法,handle方法运用Java的 反射机制执行controller的具体方法来获得ModelAndView,例如SimpleControllerHandlerAdapter是支持 实现了controller接口的控制器,如果自己写的控制器实现了controller接口,那么 SimpleControllerHandlerAdapter就会去执行自己写控制器中的具体方法来完成请求。
流程说明
1. AbstractHandlerMethodAdapter
该类是HandlerAdapter接口的简单抽象类,实现了接口定义的方法。但也并未做真正的实现,而是留给了子类。
详细说明可以看 AbstractHandlerMethodAdapter类详解 - HandlerAdapter系列二
2. RequestMappingHandlerAdapter
该类继承了 AbstractHandlerMethodAdapter 类,真正意义上实现了 HandlerAdapter 接口定义的功能。
该方法的具体过程如下:
1.校验请求,即检查是否支持当前 rqeuest 的 method 和 session
2.判断控制器是否存在 @SessionAttributes 注解,有则设置缓存,否则准备响应
3.处理器调用,返回 ModelAndView 。
详细类说明可以看 RequestMappingHandlerAdapter类详解 - HandlerAdapter系列三
3. ServletInvocableHandlerMethod
该类实现了 HandlerMethod 类,HandlerMethod创建ServletInvocableHandlerMethod,接下来调用ServletInvocableHandlerMethod的invokeAndHandle方法,其实最终是通过反射机制调用Controller中的方法。
详细类说明可以看 ServletInvocableHandlerMethod类详解 - HandlerAdapter系列七
4. 处理器调用invokeHandlerMethod方法
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ServletWebRequest webRequest = new ServletWebRequest(request, response); // 1.数据绑定 WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod); // 2.创建 ModelFactory // 添加了 @ModelAttribute,@SessionAttributes 等注解内容 ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory); // 3.创建 ServletInvocableHandlerMethod,并绑定相关属性 ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); invocableMethod.setDataBinderFactory(binderFactory); invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); // 4.创建 ModelAndViewContainer ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); modelFactory.initModel(webRequest, mavContainer, invocableMethod); mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect); // 省略部分源码... // 5.调用控制器方法 invocableMethod.invokeAndHandle(webRequest, mavContainer); // 6.返回 ModelAndView return getModelAndView(mavContainer, modelFactory, webRequest); }
5. getModelAndView方法
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception { // 更新 Mdoel modelFactory.updateModel(webRequest, mavContainer); // 判断请求是否处理器完毕 if (mavContainer.isRequestHandled()) { return null; } // 关键 -> 创建 ModelAndView ModelMap model = mavContainer.getModel(); ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model); // 判断 view 是不是字符串 if (!mavContainer.isViewReference()) { mav.setView((View) mavContainer.getView()); } // 重定向相关 if (model instanceof RedirectAttributes) { MapflashAttributes = ((RedirectAttributes) model).getFlashAttributes(); HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes); } return mav; }
版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。