类图结构
DispatcherServlet的工作大致分为两个部分
-
初始化Servlet, 由
initServletBean()
启动, 通过initWebApplicationContext()
方法最终调用DispatcherServlet
的initStrategies()
方法, 在这个方法中, 主要完成了对容器中的其他组件的初始化,例如handlerMapping
,ViewResolver
-
是对Http请求的处理, 作为一个Sevlet, 最终会调用到
doGet
和doPost
方法, 经过FrameworkServlet
方法的processRequest()
方法简单处理之后, 会调用到DispatcherServlet
的doService()
方法。
WEB中的双亲委派模型
DispatcherServlet
本身也是一个Servlet的实例, 因此, DispatcherServlet
的初始化, 实际上跟Servlet
初始化一致,在中介绍了ContextLoader
的加载过程, 会在ServletContext
中绑定ROOT
容器,那么在Servlet
中也有自己的WebApplicationContext
的实现, 并且都是ROOT
容器的子容易, 在IOC
中, 我们知道了在getBean
操作中, 会先从父容器中获取对应的bean信息,因此在ROOT
中的bean可以在各个子容器共享。
NOTE: 每一个单独的Servlet都可以拥有自己的
WebApplicationContext
的容器,他们共享一个ROOT
的容器。
加载流程
-
从
HttpServletBean
中执行init
方法 -
从
FrameworkServlet
中, 初始化当前Servlet的WebApplicationContext
的容器, 并将ROOT
设置为父容器 -
DispatcherServlet
中执行initStrategies()
方法, 初始化mvc中的容器控件
initStrategies中初始化那些东西?
-
初始化
MultipartResolver
实例 -
初始化
LocaleResolver
实例 -
初始化
ThemeResolver
实例 -
初始化
handlerMapping
实例 -
初始化
HandlerAdapter
实例 -
初始化
HandlerExceptionResolver
实例 -
初始化
RequestToViewNameTranslator
实例 -
初始化
ViewResolver
实例
HandlerMapping
从上面我们知道, 在DispatcherServlet
初始化的时候, 会从容器中寻找handlerMapping
的子类, 作为当前的HandlerMappings
的列表, 如果当前的容器中没有配置, 则使用DispatcherServlet.properties
的配置文件中获取默认的配置.
HandlerMapping
在DispatcherServlet中对应这个列表, 并且是按照顺序排列的,并且这些 HandlerMapping
存储着http的请求数据, 这里的每个HandlerMapping
都持有者一个URL
到Controller
的映射关系, Spring MVC中提供了很多的HandlerMapping
的实现,具体如下图:
getHandler
getHandler
的方法实际返回的是一个HandlerExecutionChain
的对象, 这个对象不仅包含了HandlerMapping
的本身,同时也包含了http interceptors
的拦截器的对象, 这些HandlerMappings
可以通过Ordered
的进行排序, priority
越低, 则执行的优先级越高, 如果没有设置, 则具有最低执行优先级
SimpleUrlHandlerMapping
该类是HandlerMapping
的实现类, 实现了URL
到Controller
的映射关系, 通过registerHandlers()
方法实现url
与hanlder
之间的映射关系,最终关系维护在AbstractUrlMapping
的类中, 通过Map
来进行实现。
DispatcherServlet的请求分发
View
View主要通过视图的渲染, 这里的渲染包含了生成View
的对象, 通过View
的render