SpringMVC源码流程图-@Controller注解
2021-06-23 09:59:35 0 举报
SpringMVC源码流程图-@Controller注解
作者其他创作
大纲/内容
renderMergedOutputModel
getHandlerExecutionChain
handler.triggerAfterCompletion
AbstractHandlerMethodMapping#getHandlerInternal
Object handler = lookupHandlerMethod
获取match对象
调用具体的适配器
获取处理器
applyPreHandle
HandlerAdapter ha=getHandlerAdapter
resolver.resolveArgument
HandlerExecutionChain chain = new HandlerExecutionChain(handler)
this.resolvers.supportsParameter策略模式,根据parameter能否找到对应参数的处理类,能找到就返回true,都没有就抛出异常
当前通过viewName解析到对应的view后,就可以进一步地处理跳转逻辑了
处理页面跳转逻辑
AbstractHandlerMapping#getHandlerExecutionChain
获取请求的路径/demo3/1
为调用方法设置各种值
根据java多态,调用到我们自己的方法
handler.supportsReturnType
getArgumentResolver
根据路径寻找对应的handler返回的是HandlerMethod
getBean()this.bean
创建视图
handleResolvedValue
视图渲染
这个是用来解析/{aaa}/{bbb}的抽象父类
DispatcherServlet#getHandlerAdapter
这里根据handler去寻找对应的Adater这个集合是在初始化的时候添加到handlerAdapters的
HandlerExecutionChain#applyPostHandle
处理视图的jsp
不存在缓存的情况下直接创建视图
为目标资源获取RequestDispatcher
RequestMappingHandlerAdapter#handleInternal
addMatchingMappings2.MappingInfo对象和HandlerMethod对象封装到Match对象(这里可能在第一步缓存中没查找到。开始从所有的mappingInfo中找)
处理前缀为forward:xx的情况
invokeModelAttributeMethods
this.returnValueHandlers.handleReturnValue
如果出现异常,进行异常处理
从request中拿到之前set的值
HandlerMethodReturnValueHandlerComposite#selectHandler
执行对应的handler的返回值封装方法
根据参数获取对应参数的解析类
trigerAfterCompletion
不同的参数解析器。会有不同的参数解析结果。本质就是获取到参数的名称和注解。再去逐层判断拿到args的值
根据具体的适配器,调用业务逻辑
入参的包装类,里面包装了参数类型、参数名称、参数注解等信息
doInvoke(args)
handlerMatch
其中之一
this.resolvers.resolveArgument
应用所有拦截器的postHandle方法
DispatcherServlet#render
进行转发
对跨域请求头进行一个匹配之后如果有就设置跨域处理的拦截器
View view = viewAccessCache.get(caheKey)
RequestMappingHandlerAdapter完成了@ModelAttribute注解的方法1.设置参数解析器2.设置返回值解析器等各种参数的设置
遍历所有的拦截器执行postHandle
view.render
getHandler
handlerAdapter.handle
chain.addInterceptor
render
UrlBasedViewResolver#createView
判断是否有跨域请求
如果在Handler实例的处理中返回了view,那么需要做页面的处理
AbstractView#render
viewName.startsWith(\"redirect:\")
DispatcherServlet#doDispatch
processHandlerException
getModelFactory
processDispatchResult
DispatcherServlet#processDispatchResult
将model中的数据以属性的方式设置到request中
获取处理请求的处理器适配器handlerAdapter
从集合中拿到值
这个是用来解析/{aaa}/{bbb}的抽象父类1.先调用父类AbstractNamedValueMethodArgumentResolver2.getNamedValueInfo(parameter)通过参数信息,获取方法上的注解信息3.获取到参数名,调用子类(自己)实现方法,从uriTemplateVars获取到参数的值4.处理参数信息创建pathVars,再写入request中
获取Model工厂,收集了@ModelAttribute注解的方法
获取HandlerMethod和过滤器链的包装类,最终返回HandlerExecutionChain
然后,将之前的HandlerInterceptor逐个匹配添加进去
getMethodArgumentValues
rd.forward
viewName.startsWith(\"forward:\")
执行前置处理器
HandlerAdapter#handle
ViewNameMethodReturnValueHandler#handleReturnValue
AbstractCachingViewResolver#resolveViewName
PathVariableMapMethodArgumentResolver
handler.handleReturnValue
InternalResourceView#renderMergedOutputModel
applyPostHandle
获取处理当前请求的Controller返回HandlerExecutionChain
这个值会在下面用到
检查是否是文件上传的请求
AbstractHandlerMapping#getHandler
AbstractHandlerMethodAdapter#handle
处理页面跳转
View view = createView
View#render
返回值处理
ha.supports
有缓存,直接从缓存中提取
在所有请求处理完成之后调用afterCompletion
策略的执行
判断handler是不是HandlerExecutionChain类型如果不是包装为此类型
checkMultipart
遍历所有的视图解析器,解析视图
执行前置处理器目标方法执行之前被调用
PathVariableMethodArgumentResolverresolveName
HandlerExecutionChain#applyPreHandle
interceptor.postHandle
根据请求获取对应的handler
先判断缓存中是否有,没有的话,for循环去找对应的解析器
获取对应的适配器
根据拿到的Adapter调用对应的handle方法,返回ModelAndView对象Controller具体方法的调用
重新在request中写入一个集合pathVars
RequestDispatcher rd = getRequestDispatcher
获取参数数组
exposeModelAsRequestAttributes
找到Controller接口
resolver.supportsParameter
遍历拦截器执行afterCompletion方法
interceptor.preHandle
getMatchingMapping有的话封装成match,加入matches
interceptor.afterComletion
request.setAttribute将匹配的映射参数写入到request参数中
this.mappingRegistry.getMappingsByUrl1.查url和RequestMappingInfo缓存
invocableMethod.invokeAndHandle
HandlerExecutionChain#triggerAfterCompletion
getCorsHandlerExecutionChain
getPathMatcher().extractUriTemplateVariables将占位符进行匹配操作
getHandlerInternal
CorsUtils.isCorsRequest?
uriTemplateVars.get(name)
viewResolver.resolveViewName
DisatcherServlet根据ModelAndView选择合适的视图来进行渲染
后置处理器目标方法执行之后被调用
modelFactory.initModel方法执行前,先执行@ModelAttribute的方法,并把结果记录在ModelAndViewContainer对象的map中了
匹配策略参数,返回对应的handler
AbstractHandlerMethodAdapter#handleInternal
getNamedValueInfo
AbstractNamedValueMethodArgumentResolver#resolveArgument
getUrlPathHelper().getLookupPathForRequest
invokeForRequest
View view = resolveViewName
有了参数,有了方法就可以执行反射调用了
处理前缀为redirect:xx的情况
RequestMappingHandlerAdapter#invokeHandlerMethod
遍历所有适配器,看此适配器是否符合要求,是的话,返回该适配器
0 条评论
下一页