首先看一下web.xml中DispatcherServlet的配置
创建Servlet的对象必定要调用初始化方法 init(), 我们就从init()方法开始开源码
查看DispatcherServlet的源码并没有init()方法,看一下继承关系
DispatcherServlet继承自FrameworkServlet, FrameworkServlet又继承自HttpServletBean,
HttpServletBean中有init()方法的实现,就从它的init()方法开始:
init()的方法中核心代码是initServletBean(),看该方法上面的注释
“让子类做它们喜欢的任何初始化”,也就是说子类实现这个方法,来完成其他的初始化任务。
FrameworkServlet类实现了initServletBean()方法。
initWebApplicationContext()最终是要创建一个WebApplicationContext
在创建ApplicationContext中的BeanFactory时,会解析MVC的配置文件*-servlet.xml,
通过包扫描会先把所有的Controller注册的bean定义注册到beanFactory中去,
我们主要看一下mvc标签的解析
mvc标签对应的NameSpaceHandler
对annotation-driven标签的解析是由AnnotationDrivenBeanDefinitionParser完成的下面是它的parse()方法
该方法的核心是注册实现MVC功能的一系列bean,
其中我们要关注的是RequestMappingHandlerMapping,
该类的主要作用是把每一个请求和一个controller方法形成一对一的关系,
这一步是在RequestMappingHandlerMapping实例化的时候完成的,
RequestMappingHandlerMapping的祖类AbstractHandlerMethodMapping中的afterPropertiesSet()方法
handler就是我们传入的controller对象,methods是解析controller生成的集合
mapping是请求的路径、handler就是controller对象、method就是处理请求的方法
mappingLookup、registry都是Map类型,表示请求和处理它的controller方法是一对一的关系
这也是RequestMappingHandlerMapping在初始化的时候主要完成的工作。后面DispatcherServlet
的initHabdlerMappings方法会从context中获取到RequestMappingHandlerMapping的实例,
把它作为自己的一个成员变量 handlerMappings。至此基本完成了初始化工作。
下面开始我们看一下一个Request请求是如何通过Dispatcher来映射到处理它的controller方法。
我们知道Servlet处理Request请求是通过doGet()、doPost()等方法,DispatcherServlet的父类
FrameworkServlet重载了这些方法
doService()是FrameworkServlet的一个抽象方法,DispatcherServlet实现了该方法
HandlerExecutionChain类的组成:
handler就是请求路径对应的处理器方法HandlerMethod,其他两个是该请求路径适用的拦截器的集合
HandlerAdapter主要是用来生成视图ModelAndView的