Spring 的MVC,是基于Servlet功能实现的,通过实现Servlet接口的DispatcherServlet来封装其核心功能实现。
1 启动web容器后,会有一个servletContext对象该对象是全局唯一,项目中所有Servlet都共享该对象。ContextLoaderListener 装配ApplicationContext的配置信息
1 /** 2 * Initialize the root web application context. 3 */ 4 @Override 5 public void contextInitialized(ServletContextEvent event) { 6 initWebApplicationContext(event.getServletContext()); 7 }
在该方法中会创建WebApplicationContext实例并且并调用ServletContext的setAttribute方法,将其设置到ServletContext中,
属性的key为"org.springframework.web.context.WebApplicationContext.ROOT",最后的"ROOT"说明是Root WebApplicationContext
2 DispatcherServlet初始化,根据web.xml中的配置对*-servlet.xml进行加载初始化Servlet WebApplicationContext 调用FrameworkServlet中的initWebApplicationContext方法,
并且设置ServletWebApplicationContext的parent为上面的root WebApplicationContext
protected WebApplicationContext initWebApplicationContext() { WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContext wac = null; if (this.webApplicationContext != null) { // A context instance was injected at construction time -> use it wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac; if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> set // the root application context (if any; may be null) as the parent cwac.setParent(rootContext); } configureAndRefreshWebApplicationContext(cwac); } } } if (wac == null) { // No context instance was injected at construction time -> see if one // has been registered in the servlet context. If one exists, it is assumed // that the parent context (if any) has already been set and that the // user has performed any initialization such as setting the context id wac = findWebApplicationContext(); } if (wac == null) { // No context instance is defined for this servlet -> create a local one wac = createWebApplicationContext(rootContext); } if (!this.refreshEventReceived) { // Either the context is not a ConfigurableApplicationContext with refresh // support or the context injected at construction time had already been // refreshed -> trigger initial onRefresh manually here. onRefresh(wac); } if (this.publishContext) { // Publish the context as a servlet context attribute. String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); if (this.logger.isDebugEnabled()) { this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() + "' as ServletContext attribute with name [" + attrName + "]"); } } return wac; }