一、DispatcherServlet的初始化过程
DispatcherServlet,也就是我们的前端控制器,它是SpringMVC的核心,那么,Spring容器在初始化DispatcherServlet的时候做了什么?
先看一下DispatcherServlet类的集成关系
1、调用init()方法
init()方法在在HttpServlet中定义,在HttpServletBean中有实现,
可以看到:
a、web.xml中配置的参数是通过HttpServletBean的内部类ServletConfigPropertyValues保存的
b、DispatcherServlet是通过BeanWrapper类构造完成的,并将上面的属性设置到DispatcherServlet中。为什么这样做,原因是,我们web.xml的配置
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springConfig/dispatcher-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
contextConfigLocation参数是在子类FrameWorkServlet中定义的,HttpServletBean中没有这个属性的定义,第二,利用Spring的注入,使用setPropertyValues方法就可将contextConfigLocation属性设置到对应实例中,也就是以依赖注入的方式初始化属性。(BeanWrapper是Bean的包装,可以访问Bean的属性描述器,也可以对Bean的属性进行设置获取,通过BeanWrapper,IOC容器可以用统一的方式来访问Bean的属性)。
2、FrameWorkServlet.initServletBean()方法
由上面的代码,可以知道
a、FramWorkServlet的作用就是,将Servlet和Spring通过上下文联系起来
需要注意的是,注释中的根上下文指的是web.xml中配置的ContextLoaderListener监听器中根据contextConfigLocation路径生成的上下文。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springConfig/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3、DispatcherServlet.onRefresh()
如上,此方法的作用就是初始化各个策略接口,比如
异常处理初始化initHandlerExceptionResolvers方法
视图处理初始化initViewResolvers方法
请求映射处理初始化initHandlerMappings方法
这些将在后面解释。
整个MVC的初始化工作就此完成,总结一个这几个接口/类的主要职责
1、HttpServletBean
初始化工作,将初始化参数,设置到Servlet中,比如,web.xml中servlet标签的init-para配置的参数。
2、FramWorkServlet
将Servlet与Spring容器相关联。也就是初始化属性webApplicationContext,这个参数代表的就是Spring容器的上下文,这个上下文有个父类的上下文,就是既web.xml中配置的ContextLoaderListener监听器初始化的容器上下文
3、DispatcherServlet
初始化各个组件接口,比如请求映射,视图处理,异常处理。