1. DispatcherServlet继承结构
如图所示
2.MVC请求处理的大致流程
打断点,观察调用栈可以得知,实际处理请求Handler⽅法在核心方法doDispatch中调用如下
视图页面什么时候被渲染的呢?
如下图所示,在doDispatch中1081行调⽤processDispatchResult()⽅法完成视图渲染跳转
放开断点,执行后发现SpringMVC处理请求的流程即为
org.springframework.web.servlet.DispatcherServlet#doDispatch⽅法的执⾏过程,大致如下几步
(1)检查是否文件上传
(2).调⽤getHandler()获取到能够处理当前请求的执⾏链 HandlerExecutionChain(Handler+拦截
器)
(3).调⽤getHandlerAdapter();获取能够执⾏1)中Handler的适配器
(4)适配器调⽤Handler执⾏ha.handle(总会返回⼀个ModelAndView对象)
(5)调⽤processDispatchResult()⽅法完成视图渲染跳转
2、3、4、5是核⼼步骤
3.getHandler() 方法分析
如图所示,断点进入后,会发现有两个个HandlerMapping,而我们现在实际使用的是ResquestMapping,BeanNameUrl是srping早起版本,大概 3 .4版本在xml定义时候,会使用到这个实现类;HandlerMapping中映射关系在容器启动时,扫描注解后,建立了url和hanlder之间的映射关系
4.getHandlerAdapter()适配器获取分析
如图,HandlerAdapter有三个实现类,不同实现处理不同方式定义的handler,遍历各个HandlerAdapter,看哪个Adapter⽀持处理当前Handler
5.SpringMvc九大组件初始化
九大组件如下,在DispatcherServlet中的onRefresh(),该⽅法中调用了initStrategies方法初始化了九⼤组件
/** MultipartResolver used by this servlet. */
// 多部件解析器
@Nullable
private MultipartResolver multipartResolver;
/** LocaleResolver used by this servlet. */
// 区域化 国际化解析器
@Nullable
private LocaleResolver localeResolver;
/** ThemeResolver used by this servlet. */
// 主题解析器
@Nullable
private ThemeResolver themeResolver;
/** List of HandlerMappings used by this servlet. */
// 处理器映射器组件
@Nullable
private List<HandlerMapping> handlerMappings;
/** List of HandlerAdapters used by this servlet. */
// 处理器适配器组件
@Nullable
private List<HandlerAdapter> handlerAdapters;
/** List of HandlerExceptionResolvers used by this servlet. */
// 异常解析器组件
@Nullable
private List<HandlerExceptionResolver> handlerExceptionResolvers;
/** RequestToViewNameTranslator used by this servlet. */
// 默认视图名转换器组件
@Nullable
private RequestToViewNameTranslator viewNameTranslator;
/** FlashMapManager used by this servlet. */
// flash属性管理组件
@Nullable
private FlashMapManager flashMapManager;
/** List of ViewResolvers used by this servlet. */
// 视图解析器
@Nullable
private List<ViewResolver> viewResolvers;
onRefresh()调用时机:
重点关注refresh方法,是spring容器加载的一个方法,在此方法的最后有一个finishRefresh()方法进行事件发布,触发事件监听,最终调用到onRefresh()方法
initHandlerMappings(context)初始化细节
如果按照类型和按照固定id从ioc容器中找不到对应组件,则会按照默认策略进⾏注册初始化,默
认策略在DispatcherServlet.properties⽂件中配置
multipartResolver多部件析器
多部件解析器的初始化必须按照id注册对象