在SpringMVC项目中除了spring容器(根上下文),DispatcherServlet也会建立一个自己的IoC容器来持有springmvc的bean对象,在建立这个容器时,会从ServletContext中获取根上下文作为自己的双亲上下文,它可获取双亲上下文中的bean,DispatcherServlet的IoC容器也会存到ServletContext中。
DispatcherServlet是一个servlet,回想servlet的生命周期,servlet在初始化的时候调用的是init方法,那么就从init方法开始看一下DispatcherServlet对SpringMVC的初始化。
继承关系图:
1.HttpServletBean
HttpServletBean是DispatcherServlet的父类,init方法是在HttpServletBean中实现的。
1 | public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware { |
HttpServletBean除了获取servlet初始化参数,还调用了initServletBean方法,进行具体的初始化,这个方法是在FrameworkServlet中实现的。
2.FrameworkServlet
FrameworkServlet同样是DispatcherServlet的父类。
DispatcherServlet的IoC容器的初始化
在initServletBean方法中,调用了initWebApplicationContext方法来初始化IoC容器,在初始化容器的方法中:
首先从ServletContext中获取了根上下文,然后判断DispatcherServlet的容器wac是否为空,如果不为空就将根上下文设置为双亲上下文,然后调用configureAndRefreshWebApplicationContext方法,完成容器的初始化。
如果容器为空,就调用createWebApplicationContext创建容器,默认使用的是XmlWebApplicationContext,创建容器的时候将根上下文作为参数传入,创建之后同样将根上下文设置为双亲上下文。
DispatcherServlet的容器也会被设置到SerletContext中,使用的属性名是和
当前Servlet的名称。在createWebApplicationContext创建容器的方法中,最后调用了configureAndRefreshWebApplicationContext方法,在该方法中调用了容器的refresh方法,之后就与spring IoC容器的初始化过程一致了。
之后,SpringMVC的上下文就建立起来了,意味着DispatcheServlet拥有自己的Bean定义空间,为使用各个独立的XML文件来配置MVC中的各个bean创建了条件。
SpringMVC的初始化
在initWebApplicationContext方法中,在容器创建完成后,有一步是调用this.onRefresh方法,这个方法是在DispatcherSerlet中实现的,在该方法中完成了SpringMVC的初始化。
1 | public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware { |
WebApplicationContextUtils
取得根上下文的过程是在WebApplicationContextUtils中实现的。在getWebApplicationContext方法中,先调用WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE获取根上下文在ServletContext中的属性名,然后从ServletContext中获取根上下文,转换为WebApplicationContext返回。
1 | public abstract class WebApplicationContextUtils { |
3.DispatcherServlet
在FrameworkServlet的configureAndRefreshWebApplicationContext方法中,最后一步是调用onRefresh方法,这个方法是在DispatchServlet中实现的。
在onRefresh方法中,调用了initStrategies方法,这个方法中启动了SpringMVC框架的初始化。
1 | public class DispatcherServlet extends FrameworkServlet { |
以HandlerMapping为例,HandlerMapping是为HTTP请求寻找对应的Controller控制器,在HandlerMapping初始化过程中,从IoC容器中获取在配置文件中配置好的,以HandlerMapping为例:
1 | private void initHandlerMappings(ApplicationContext context) { |
参考:
spring技术内幕:深入解析spring架构与设计原理
Spring版本:5.0.5