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