SpringMvc自身创建的过程
mvc中的servlet一共有三个层次,分别为HttpServletBean FrameworkServlet DispatcherServlet其中第一个是直接继承httpServlet 第二个是初始化webapplicationContext 第三个是初始化自身的9大组件
DispatcherServlet
主要使用OnRefresh调用initStrategies初始化9大组件
如initLocalResolver:首先通过在webApplicationContext。context.getBean在容器中找到相应的组件,
能获取则获取不能获取则采用getDefaultStrategy来实现,getDefaultStrategy()实际创建的方法使用的是ClassUtils.forName() 其中需要的className是通过静态代码块加载进来的,静态代码块是在DispatcherServlet的DEFAULT_STRATEGIES_PATH中定义的键值对
了解请求从servlet到springMVC再到DispatcherServlet都处理了些什么
1.httpservletBean主要参与创建不涉及请求处理
2.(servlet处理流程是从service开始,在httpservlet根据请求的类型不同路由到(doGet doPost..)然后返回只有header没有body的Response)
而FrameworkServlet中 所有需要进行自己处理的请求(doGet doPost)等都交由processRequest进行处理而processRequest核心语句是doService,此为一个模板的方法,具体实现在dispatcherServlet具体实现
processRequest总共做了三件事,另外两件事情是2.将当前请求的LocaleContext和ServletRequestAttributes在处理请求前设置到了LocalContextHolder,并在请求处理完成后恢复
第三件事是发布了ServletRequestHandledEvent消息
3.DispatcherServlet,:处理的入口方法是doService > doDispatch进行具体处理 》首先判断是否是include请求,如果是则对request的Attribute进行快照备份,等doDispatch处理完之后进行还原
doDispatch:主要实现源码
1.根据request找到Handler
2.根据handler找到对应的handlerAdapter
3.通过HandlerAdapter处理handler
4.调用processDispatchResult处理上面的处理结果(找到view并输出给用户)
总结dodispatch流程:
检查是否是上传请求(MultipartResolver) > 找到对应的Handler(handlerMapping)>
核心:找到handlerAdapter(HandlerAdapter) > 处理Intercepter的preHandle方法 > HandlerAdapter使用Handler进行请求处理 > 判断是否需要异步处理 > 执行 Intercspter的postHnadle方法
>> 异常的处理的HandlerExceptionResolver(处理中的异常) > 渲染页面 (LocaleResolver + ViewResolver + ThemaResolver)
组件大致了解
HandlerMapping:
该接口只有方法 HandlerExecutionChain getHandler(HttpServletRequest request ) thows Exception
查找handlerMapping可以通过order定义遍历顺序。order越小越先使用
<bean class = "com.hha.zhang " p : order = "1">查找handlerMapping是找到一个handlerMapping后立即停止查找并返回
HandlerAdapter:总共存在三个方法:
1.supports() >判断是否可以使用某个handler ;
2.handler() 是用来具体使用handler干活
3.LastModified()记录资源最后一次修改的时间
HandlerExecptionResolver
专门的角色用于对异常的情况进行处理,根据异常设置modelAndView然后交由给render进行渲染,该组件不能处理render过程中的异常,改接口只有一个方法resolveException
ViewResolver
用来将String类型的视图名和local解析为view类型的视图,该接口也只有一个方法 resolveViewName()
其做的主要工作是:将程序返回的参数填入模板中,生成html的文件,两个关键的问题是:使用哪个模板。以及用什么技术填入参数
RequestToViewNameTranslator
用于根据viewName查找view ,但是有的handler处理完以后没有设置view 也没有viewName然后就得从Reauest中获取,此时就用该接口,其中有一个getViewName方法,只要通过request获取到viewName就可以了
LocalResolver
解析视图需要两个参数一个是视图名称 一个是locale ,视图名称通过处理器返回或者通过RequestToViewNameTranslator在Request中获取
local就是从localResolver中获取
local:(是zh-cn 之类 表示一个区域,有了这个就可以对不同区域的用户显示不同的结果,这就是i18n国际化的基本原理,localeResolver是i18n的基础)
ThemeResolver
用于解析主题使用的有一个接口是setThemeName()
MultiPartResolver
用于处理上传请求的,处理方式是通过将普通的request包装成Muitipart-HttpServletRequest,后者可以通过getfile的方法获取File如果上传多个文件,还可以调用gerFileMap得到FileName > file的结构map,因为上传可以不用multiResolver可以直接使用原来的request,所以该组件在springmvc中每没有提供默认值
FlashMapManager
flashmap的主要作用是在 redirect中传递参数,该manager是管理flashmap的
详细了解HandlerMapping , HandlerAdapter,HandlerExceptionResolver ,
处理器映射器 处理器适配器 异常处理器
handlermapping:继承结构图
AbstractHandlerMapping:先找handler 再通过getHandlerExecutionChain添加拦截器
找handler的过程:
1.通过getHandlerInternal(request)的方法获取,这是个模板方法,留给子类实现
2.如果没有获取到,则使用默认的handler,默认的handler在abstractHandlerMapping的一个object类型的属性defaultHandler中,
3.如果找到了的话handler是String类型,则去spirngMvc容器中找到相应的bean
AbstractUrlHandlerMapping总结:
首先在abstractIUrlHandlerMapping中涉及了整体的架构,并完成了查找handler的具体逻辑,其中需要板寸一个ur和handler的对应关系map,map留给子类SimpleUrlHandlerMapping进行初始化,通过调用registerHandler方法,初始化实现两种方式,一种是在陪孩子文件中配置,一种是在spring容器里查找
AbstaractHnadlerMethodMapping系列
该系列是Method作为handler来使用,这也是我们用的最多的一种handler,比如常用的@RequestMapping锁注释的方法就是这种handler
其中有三个map:handlerMethods ;urlmap;nameMap
handlerMethods:用于保存匹配条件(RequestConditon)和handlerMethod的对应关系
urlMap:保存着url和匹配条件(RequestConditon)的对应关系,这里的url是pattern,该map是MultiValueMap是一个key对应多个值的map
MultiValueMap<K,V> extends Map<K, List<V>>
namemap:该map保存name和HandlerMethod的对应关系,
处理逻辑:urlmap 先匹配url获取匹配原则,可能有多个匹配原则然后根据handlerMethods获取到handlerMethod,urlmap可能有多个匹配原则,有时候需要选择最优的找到handlermethod
HandlerMapping:AbstractHandlerMapping分为两个系列一个是AbstratctUrlHandlerMapping一个是AbstractHandlerMethodMapping,前者是通过url进行匹配的,后这匹配的内容较多,而且是直接匹配的Method
HandlerAdapter
最难得是AbstractHandlerMethodAdapter
handlerAdapter一共有三个方法:一个是判断是否支持,一个是用于处理handler请求,最后一个是用来获取资源的Last-Modified
后面三种分别适配httpRequestHandler Servlet Controller的Handler