Spring MVC的工作机制
Spring MVC的工作机制
Spring MVC的总体设计
使用Spring MVC,需要:
- 拓展一个路径映射器
- 定义一个视图解析器
- 定义一个业务逻辑的处理流程规则
在Service的init方法调用时,DIspatcherServlet执行SpringMVC的初始化方法,主要初始化的内容,可以在initStrategies方法中得知,主要包含以下八个流程:
- initMultipartResolver:用于处理文件上传服务
- initLocaleResolver:用于处理应用的国际化问题
- initThemeResolver:用于定义一个主题,例如可以根据用户的喜好来设置用户访问的页面样式
- initHandlerMappings:用于定义用户设置的请求映射关系
- initHandlerAdapters:用于根据Handler的类型定义不同的处理规则
- initHandlerExceptionResolvers:当Handler处理出错时,会通过这个Handler来统一处理
- initRequestToViewNameTranslator:将指定的ViewName按照定义的RequestToViewNameTranslator替换成想要的格式
- initViewReslovers:用于将View解析成页面
在SpringMVC框架中,有三个组件是用户必须要定义和拓展的:
- 定义URL映射规则
- 实现业务逻辑的Handler实例对象
- 渲染模板资源
连接Handler实例对象和模板渲染的纽带就是Model模型
Control设计
SpringMVC的Control主要由HandlerMapping和HandlerAdapters两个组件提供
HandlerMapping初始化
SpringMVC本身提供了很多HandlerMapping的实现,默认使用BeanNameUrlHandlerMapping,可以根据Bean的name属性映射到URL
SpringMVC提供的几种HandlerMapping实现类基本上都是基于配置的实现方式,也就是URL的所有匹配规则都需要我们在配置文件中定义,这种方法既有优点也有缺点。优点是一看配置文件就可以知道这个应用的URL映射关系,缺点是如果需要映射的URL很多,会导致配置文件非常庞大,URL的映射关系会很难管理
HandlerMapping的初始化工作完成的两个最重要的工作就是将URL与Handler的对应关系保存在handlerMap集合中,并将所有的interceotors对象保存在adaptedInterceptors数组中,等到请求来的时候执行所有的adatedInterceptors数组中的interceptor对象
HandlerAdapter初始化
在HandlerMapping完成URL与Handler的映射关系后,HandlerAdapter就可以帮助自定义各种Handler
在SpringMVC中提供了三种典型的简单HandlerAdapter实现类:
- SimpleServletHandlerAdapter
- SimpleControllerHandlerAdapter
- SimpleServletHandlerAdapter
其初始化过程大致为:
- 简单创建一个HandlerAdapter对象
- 将这个对象保存在DispatcherServlet的handlerAdapters集合中
- 当某个URL对应到某个Handler时,在集合中查询那个对象supports这个Handler,HandlerAdapter对象将被返回并调用这个接口对应的方法
Model设计
如果Handler对象返回了ModelAndView对象,那么说明Handler需要传一个Model实例给View去渲染模板
ModelAndView对象是连接业务逻辑层与View表现层的桥梁,对于SpringMVC来说也是连接Handler与View的桥梁。其会持有一个ModelMap对象和一个View对象或者View的名称。ModelMap对象就是执行模板渲染时所需要的变量对应的实例
ModelMap也是一个Map,在Handler中将模板中需要的对象存在这个Map中,然后传递到View对应的ViewResolvers中
View设计
对于SpringMVC的View模块来说,由两个组件支持:
- RequestToViewNameTranslator:支持用户自定义对ViewName的解析,如将请求的ViewName加上前缀或者后缀或者替换成特定的字符串
- ViewResolver:根据用户请求的ViewName创建合适的模板引擎来渲染最终的页面
viewNameTranslator的初始化就是让Spring创建的Bean的对象保存在DispatcherServlet的viewNameTranslator属性中