ServletContext

ServletContext是WEB利用的全局的贮存信息的空间,服务器启动就创立,服务器敞开则销毁,即利用上下文

Spring容器的初始化

WEB利用启动时,ServletContext初始化,Spring提供的ContextLoaderListener会监听到这个事件,ContextLoaderListener.contextInitialized办法会被调用

// 在这个办法中,Spring会初始化根上下文,即WebApplicationContextinitWebApplicationContext(event.getServletContext()) 

WebApplicationContext理论的实现类是XmlWebApplicationContext,这个就是Spring的IOC容器,对应治理的Bean的定义由web.xml中的context-param标签指定(即applicationContext.xml)
在这个IOC容器初始化结束后,Spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取

SpringMVC的启动过程

web.xml中的配置

<servlet><servlet-name>service_dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/spring/services/service_dispatcher-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet>

这段配置会初始化DispatcherServlet,load-on-startup示意启动容器时初始化该Servlet

  • SpringMVC启动的过程,实际上是DispatcherServlet的初始化过程
    DispatcherServlet 继承关系为 FrameworkServlet -> HttpServletBean -> HttpServlet -> Servlet,通过应用Servlet API 来对HTTP申请进行响应,成为SpringMVC的前端处理器,用以转发、匹配、解决每个申请。

  • DispatcherServlet初始化从HttpServletBean笼罩父类的init办法开始
public final void init() throws ServletException {    if (logger.isDebugEnabled()) {        logger.debug("Initializing servlet '" + getServletName() + "'");    }    // Set bean properties from init parameters.    try {    // 取得web.xml中的contextConfigLocation配置属性(即springmvc-config.xml),Spring MVC的配置文件    PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);    BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);    // 获取ServletContext    ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());    bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));    // 模板办法,能够在子类中调用,做一些初始化工作,bw代表DispatcherServelt    initBeanWrapper(bw);    // 将配置的初始化值设置到DispatcherServlet中    bw.setPropertyValues(pvs, true);    }    catch (BeansException ex) {        logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);        throw ex;    }    // Let subclasses do whatever initialization they like.    // 模板办法,子类初始化的入口办法    initServletBean();    if (logger.isDebugEnabled()) {        logger.debug("Servlet '" + getServletName() + "' configured successfully");    }}

HttpServletBean中通过Spring的委托类BeanWrapper来对DispatcherServlet设值,并在FrameworkServlet.initServletBean()中进一步初始化上下文

FrameworkServlet利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE从ServletContext中获取Spring的根上下文(即WebApplicationContext)作为父上下文

DispatcherServlet取得了父上下文之后,在其initStrategies初始化处理器映射、视图解析等。初始化结束后,Spring以与Servlet的名字相干(此处不是简略的以Servlet名为Key,而是通过一些转换)的属性为属性Key,也将其存到ServletContext中,以便后续应用

  • 故,在applicationContext.xml中将@Controller正文的组件排除在外,而在dispatcherServlet加载的配置文件中将@Controller正文的组件加载进来,不便DispatcherServlet进行管制和查找