一 SpringMVC运行原理
二 SpingMVC源码分析
1 DispatcherServlet
1.1 DispatcherServlet继承结构
ServletConfig对象获取Init标签中的配置信息
1.1.1 HttpServletBean
HttpServletBean复习了init方法,主要做一些初始化的工作麻将web.xml中配置的参数
设置到Servlet中。比如servlet标签中的子标签init-param标签中配置的参数
1.1.1.1 ServletConfigPropertyValues
ServletConfigPropertyValues是HttpServletBean的静态内部类。在其构造方法中通
过传递的ServletConfig对象对web.xml文件中的DispatcherServlet节点中的参数及
及逆行解析处理
1.1.1.2 BeanWrapper bw =PropertyAccessorFactory.forBeanPropertyAccess(this):
将 HttpServletBean 类型转换为 BeanWrapper 类型,从而能对 init-parameter 的
值进行注入。
1.1.1.3 bw.registerCustomEditor(Resource.class,
newResourceEditor(resourceLoader,getEnvironment())):
注册自定义属性编辑器,遇到 Resource 类型的属性将会使用 ResourceEditor 进行解析
1.1.1.4 initBeanWrapper(bw):该方法并未做什么,为了留给子类覆盖。
1.1.1.5 bw.setPropertyValues(pvs,true): 设置 DispatcherServlet 属性
1.1.1.6 initServletBean(): 调用在 FrameworkServlet 中覆盖的该方法
* 当spingmvc启动时会调用init方法获取inint标签中属性的值,将值封装到
ProperValues中
1.1.2 FrameworkServlet
将 Servlet 上下文与 Spring 容器上下文关联。其实也就是初始化 FrameworkServlet
的属 性webApplicationContext , 这 个 属 性 代 表 SpringMVC 上 下 文 对 象 , 实
际 类 型ConfigurableWebApplicationContext。如果项目中用到spring了那么它有个
父容器,既web.xml 中配置的 ContextLoaderListener 监听器初始化的容器上下文。
1.1.2.1 this.webApplicationContext = initWebApplicationContext():
可以看到,最重要的就是
this.webApplicationContext=initWebApplicationContext(); 这段代码,这个方法的
作用是创建或刷新 WebApplicationContext 实例。如果项目中使用 到了 spring,则
进行父子容器关联。
1.1.2.2 initWebApplicationContext()方法:
如果项目中使用 spring 框架,并且在 web.xml 文件中配置了 Listener 来启动 spring。那 么在监 听器中 spring 会创建 WebApplicationContext 容器。 此时会将 该容器转换 为 ConfigurableWebApplicationContext 即 SpringMVC 容器。
如果没有在 web.mxl 文件中配置 Listener 那么此时 webApplicationContext 为 空 则 去
ServletContext 中 根 据 attrname 查 找 。 如 果 为 找 到 , 执 行
createWebApplicationContext 方法来创建 SpringMVC 的容器。
1.1.2.3 createWebApplicationContext(rootContext):
1.1.2.4 createWebApplicationContext(ApplicationContext parent)
1.1.2.5 configureAndRefreshWebApplicationContext
(ConfigurableWebApplicationContextwac):
1.1.2.6 refresh():
解析配置文件初始化 SpringMVC 的 IOC 容器环境。 解析 springmvc 配置文件:
初始化所有的bean对象
解析命名空间
1.1.3DispatcherServlet
1.1.3.1 ContextRefreshListener
1.1.3.2 onRefresh(ApplicationContextcontext):
1.1.3.3 initStrategies(ApplicationContextcontext): 初始化 SpringMVC 其他组件:如多
部件解析器、处理器映射器、处理器适配器、视图解析器等。
2 HandlerMapping接口
2.1 初始化HandlerMapping接口
2.1.1initStrategies
2.1.2initHandlerMappings
2.2HandlerMapping 接口介绍
作用是根据当前请求的找到对应的Handler(HandlerMethod(Controller 中的方法)、
Controller 对 象 ),并将Hanler与一堆HandlerInterceptor (拦截器)封装到
HandlerExecutionChain 对象中。在HandlerMapping接口的内部只有一个方法
HandlerExecutionChaingetHandler(HttpServletRequestrequest);
2.3HandlerMapping 接口实现类
HandlerMapping 实现类有两个分支,分别继承自
AbstractHandlerMethodMapping(得 到 HandlerMethod)和
AbstractUrlHandlerMapping(得到 Controllert),它们又统一继承于
AbstractHandlerMapping。
2.3.1 AbstractHandlerMapping抽象类
它实现了 HandlerMapping 接口中的 getHandler() 方法
2.3.1.1 AbstractHandlerMethodMapping
AbstractHandlerMethodMapping 这个分支获取的 Handler 的类型是
HandlerMethod,即 这个Handler 是一个方法,它保存了方法的信息(如
Method),这样一个 Controller 就可 以处理多个请求了。
上述代码中 lookupHandlerMethod() 方法主要工作是在 Map<T, HandlerMethod>
handlerMethods 中找到 HandlerMethod,这里的 T 是 HandlerMappingInfo,它
封装了 @RequestMapping 注解中的信息(url),HandlerMethodshurl对应的方法。
2.3.1.2 AbstractUrlHandlerMapping 抽象类
AbstractUrlHandlerMapping 这个分支获取的 Handler 的类型实际就是一个
Controller类。
3 HandlerAdapter 接口
SpringMVC 中使用适配器模式来解决不同的 Handler 的执行。根据 Handler 来找到支
持它的HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到
ModelAndView 对 象。
3.1接口中的抽象方法
booleansupports(Objecthandler); 判断是否支持传入的 Handler ModelAndView
handle(HttpServletRequest request, HttpServletResponse response, Object
handler) :用来使用 Handler 处理请求
long getLastModified(HttpServletRequest request, Object handler); 用 来 获 取 资
料 的 Last-Modified 值
3.2 HandlerAdapter继承结构
3.3 AbstractHandlerMethodAdapter 抽象类
利用 RequestMappingHandlerMapping 获取的 Handler 是 HadnlerMethod 类型,
它代 表 Controller 里要执行的方法。handlerInternal 是子类
RequestMappingHandlerAdapter 中的 方法。
3.4 RequestMappingHandlerAdapter 类
RequestMappingHandlerAdapter 实际就是执行@RequestMapping 注解的方法
3.4.1 handleInternal 方法
在 handlerInternal 方法中通过调用 invokeHandleMethod 方法执行
HandlerMethod 并返回 一个 ModelAndView。
3.4.2invokeHandleMethod 方法
3.5 HttpRequestHandlerAdapter 类
HttpRequestHandlerAdapter 。 是 HttpRequestHandler 的 适 配 器 可 以 执 行
HttpRequestHandler 类型的 Handler。其实就是 Controller 中的 handleRequest 方法
3.6 SimpleControllerHandlerAdapter 类
SimpleControllerHandlerAdapter 是 Controller 实现类的适配器类,其本质也是执行
Controller 中的 handleRequest 方法。
3.7 SimpleServletHandlerAdapter 类
SimpleServletHandlerAdapter 其实是一个 Servlet 的适配器,其最终执行的方法是
Servlet 的 service 方法、
3.8Debug 走读 DispatcherServlet 中初始化处理器适配器
3.8.1在配置文件中配置<mvc:annotation-driven/>
{org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA
dapter#0=org.springframework.web.servlet.mvc.method.annotation.RequestMapping
HandlerAdapter@4e afea11, org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter=org.springframew
ork.we b.servlet.mvc.HttpRequestHandlerAdapter@1a4d6190, org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter=org.springfra
mewor k.web.servlet.mvc.SimpleControllerHandlerAdapter@710d6556}
3.8.2未在配置文件中配置<mvc:annotation-driven/>
[org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@508cddf9,
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@688a3991,
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
@6f15d959]
4 ViewResolver 接口
根据视图的名称将其解析为 View 类型的视图,如通过 ModelAndView 中的视图名称 将
其解析成 View,View 是用来渲染页面的,也就是将 Model 填入模板中,生成 html 或
其他格式的文件。
4.1接口中抽象方法
ViewresolveViewName(StringviewName,Localelocale)throwsException;
4.3AbstractCachingViewResolver 抽象类
AbstractCachingViewResolver 是带有缓存的 ViewResolver,它每次解析时先从缓存里
查 找,如果找到视图就返回,没有就创建新的视图,且创建新视图的方法由其子类实现。
4.3.2 createView方法
通过调用不同的子类中的 loadView 来指定不同视图解析器处理视图。
4.4ResourceBundleViewResolver 类
ResourceBundleViewResolver 根据 views.properties 文件来解析视图,这个文件应位于
classpath 路径下
4.5XmlViewResolver 类
XmlViewResolver 根据 xml 文件来解析视图
4.6UrlBasedViewResolver 类
UrlBasedViewResolver 提供了拼接 URL 的方式来解析视图,通过 prefix 属性拼接一 个
前缀,通过 suffix 属性拼接一个后缀,就得到了视图的 URL。还可以加入 redirect: 与、
forword: 前缀,使用 redirect: 前缀会调用 HttpServletResponse 对象的
sendRedirect() 方法 进行重定向,使用 forword: 前缀会利用 RequestDispatcher 的
forword 方式跳转到指定的地 址。另外,使用时还要指定 viewClass 属性,表示要解析
成哪种 View。
4.7InternalResourceViewResolver 类
InternalResourceViewResolver 是 UrlBasedViewResolver 的 子 类 , 将
InternalResourceView 作为默认的 View 类,但如果当前 classpath 中有 jstl 的 jar 包
时则 使用 JstlView 作为 view 来渲染。
4.7.1 UrlBasedViewResolver 类
4.7.2InternalResourceViewResolver 类
5 View接口
视图渲染器,在该接口中定义了渲染视图的抽象方法。 何为渲染:所谓渲染其实就是将
Model 中的数据放到 HttpServletRequest 中传递 jsp。
void render(Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response)throwsException;
5.1 结构结构
5.2 InternalResourceView 类
继承自 AbstractUrlBasedView 抽象类的类,表示 JSP 视图
5.3Debug 走读 ViewResolver
5.3.1DispatcherServlet 初始化视图解析器