11. Spring Framework MVC 处理流程
2022-03-18 17:46:58 0 举报
AI智能生成
Spring Web MVC 处理流程
作者其他创作
大纲/内容
DispatcherServlet.initStrategies(context)<br>把 Spring 容器上下文传入,完成九大组件的初始化<br>
initMultipartResolver(context)<br>初始化文件上传解析器<br>
initLocaleResolver(context)<br>初始化国际化解析器
initThemeResolver(context)<br>初始化主题解析器
initHandlerMappings(context)<br>初始化请求处理映射器
getDefaultStrategies(context, HandlerMapping.class)<br>创建框架为我们默认提供的 HandlerMapping 实例
createDefaultStrategy(context, clazz)<br>通过 Spring 创建实例对象(所以最终会放到 Spring 容器中)
initHandlerAdapters(context)<br>初始化请求处理适配器
initHandlerExceptionResolvers(context)<br>初始化异常解析器
initRequestToViewNameTranslator(context)<br>初始化请求转视图名翻译器
initViewResolvers(context)<br>初始化视图解析器
initFlashMapManager(context)<br>初始化闪存管理器
RequestMappingInfoHandlerMapping.afterPropertiesSet()<br>由于它实现了 InitializingBean 接口,所以会回调这个方法
initHandlerMethods()<br>初始化组件映射
getCandidateBeanNames()<br>从 Spring 容器中获取所有的组件
processCandidateBean(beanName)<br>对每个组件循环处理
isHandler(beanType)<br>如果类上有 @Controller 或 @RequestMapping 注解就调用下面方法分析
detectHandlerMethods(beanName)<br>分析映射方法
getMappingForMethod()<br>获取标注了 RequestMapping 注解的所有方法
registerHandlerMethod()<br>注册到【mappingRegistry】属性中
DispatcherServlet.doDispatch()<div>它本质上是一个 HttpServlet<br><span style="font-size: inherit;">Spring MVC 用它来处理所有请求</span></div>
checkMultipart(request)<br>检查是否是文件上传请求
multipartResolver.isMultipart(request)<br>使用文件上传解析器判断<br>实际上就是判断请求头中的 Content-Type 是否以 multipart 开头
getHandler(processedRequest)<br>获取 handler 处理器<br>注意这里的返回值是 handler 处理器链<br>
mapping.getHandler(request)<br>循环所有的 handlerMappings,看哪一种可以获取到 handler 处理器<br>这里使用 RequestMappingInfoHandlerMapping 映射器
getHandlerInternal(request)<div>根据请求路径从【mappingRegistry】注册器中查找对应的 HandlerMethod</div>
getHandlerExecutionChain()<br>从容器中获取所有的【HandlerInterceptor】拦截器<br>将 handler 封装成 HandlerExecutionChain 返回<br>
getHandlerAdapter(mappedHandler.getHandler())<br>循环所有的 handlerAdapter 适配器,看哪一种符合<br>这里使用 RequestMappingHandlerAdapter 适配器<br>
adapter.supports(handler)<br>调用这个方法判断是否支持处理当前 handler
mappedHandler.applyPreHandle(processedRequest, response)<br>顺序触发拦截器的 preHandle() 请求,如果未通过直接 return
ha.handle()<br>执行 handler
invokeHandlerMethod()<br>继续执行
getDataBinderFactory(handlerMethod)<br>创建数据绑定器工厂
getModelFactory(handlerMethod, binderFactory)<br>创建模型工厂
创建 ModelAndViewContainer 对象
判断是否是异步处理
invokeAndHandle()<br>执行目标方法<br>
invokeForRequest()<br>目标方法的反射执行过程
getMethodArgumentValues()<br>处理请求参数
resolvers.supportsParameter(parameter)<br>先校验解析器是否支持解析这个参数,不支持直接抛出异常
HandlerMethodArgumentResolverComposite.supportsParameter()<br>它相当于一个门面,组合了所有的参数解析器,在这里循环判断是否支持
argumentResolverCache.get(parameter)<br>先从缓存中获取结果<br>即每个方法的每个参数与 HandlerMethodArgumentResolver 会绑定缓存
resolver.supportsParameter(parameter)<br>判断 resolver 参数解析器是否支持
argumentResolverCache.put(parameter, result)<br>放到缓存中
this.resolvers.resolveArgument()<br>调用参数解析器的解析方法<br>这里直接从缓存中获取参数解析器调用解析方法
doInvoke(args)<br>上面步骤已经解析好了参数,这里直接通过反射执行目标方法
handleReturnValue()<br>处理返回值
selectHandler()<br>获取返回值处理器
handler.supportsReturnType(returnType)<br>在这里循环所有的【returnValueHandlers】返回值处理器,最终查找到支持的处理器<br>
handleReturnValue()<br>处理返回值结果<br>
getModelAndView()<br>将结果封装成 ModelAndView 对象返回<br>这里可能已经提前给用户发出了响应(如 json 数据)
初始化 ModelAndView 对象
mappedHandler.applyPostHandle(processedRequest, response)<br>倒叙触发拦截器的 postHandle() 方法
processDispatchResult()<br>处理派发结果
processHandlerException()<br>如果有异常就处理异常
resolver.resolveException()<br>调用异常处理器的异常处理方法
render(mv, request, response)<br>渲染模型结果
resolveViewName()<br>根据视图名称获取视图对象<br>即根据返回的 "index" 字符串查找 index.jsp 文件
viewResolver.resolveViewName()<br>调用视图解析器的视图解析方法,获取视图对象
AbstractCachingViewResolver.resolveViewName()<br>根据返回值创建不同的视图,这里也会有缓存
createView()<br>创建视图
如果 “redirect:” 开头,创建 RedirectView 对象<br>
如果 “forward:” 开头,创建 InternalResourceView 对象
其它情况创建 InternalResourceView 对象
view.render(mv.getModelInternal(), request, response)<br>渲染视图结果
createMergedOutputModel()<br>创建模型数据
renderMergedOutputModel()<br>渲染模型
exposeModelAsRequestAttributes()<br>暴露 model 中的数据到请求域中<br>实际上就是调用 request.setAttribute() 方法放置属性
rd.forward(request, response)<br>转发到对应的视图页面<br>根据不同的视图对象有不同的处理方式,这里以 InternalResourceView 为例i
HandlerExecutionChain.triggerAfterCompletion(processedRequest, response)<br>倒叙触发拦截器的 afterCompletion() 方法<br>这个方法无论如何都会被执行
0 条评论
下一页