Spring MVC的web.xml文件的分析

###web.xmlweb

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:dispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

###ContextLoaderListener的做用 ContextLoaderListener的做用是初始ApplicationContext(默認的是XmlWebApplicationContext)而後將其放在ServletContext中。spring

initWebApplicationContext方法中的下面代碼mvc

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

configureAndRefreshWebApplicationContext根據配置文件初始化bean
配置文件片斷:
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:dispatcher-servlet.xml</param-value>

讀取配置文件源碼片斷:
configLocationParam = sc.getInitParameter("contextConfigLocation");
if(configLocationParam != null) {
    wac.setConfigLocation(configLocationParam);
}

####ServletContext做用app

  1. 每個web應用都有一個 ServletContext與之相關聯。ui

  2. ServletContext對象在應用啓動的被建立,在應用關閉的時候被銷燬。this

  3. ServletContext在全局範圍內有效,相似於應用中的一個全局變量。url

###DispatcherServlet的做用 DispatcherServlet類圖spa

####HttpServletBean做用 HttpServletBean的做用主要是作一些初始化,講web.xml中配置的參數設置到Servlet中debug

//好比初始化init-param中的參數 <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:dispatcher-servlet.xml</param-value> </init-param>code

//源碼片斷
HttpServletBean.ServletConfigPropertyValues ex = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ServletContextResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
this.initBeanWrapper(bw);
bw.setPropertyValues(ex, true);

####FrameworkServlet做用 FrameworkServlet的做用講Servlet和Spring容器關聯。其實也就是初始化FrameworkServlet的屬性webApplicationContext,這個屬性表明SpringMVC上下文,它有個父類上下文,既web.xml中配置的ContextLoaderListener監聽器初始化的容器上下文。

//源碼片斷
protected WebApplicationContext initWebApplicationContext() {
 //這個設置springMVC的父類上下文爲ContextLoaderListener初始化的容器上下文
        WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        WebApplicationContext wac = null;
        if(this.webApplicationContext != null) {
            wac = this.webApplicationContext;
            if(wac instanceof ConfigurableWebApplicationContext) {
                ConfigurableWebApplicationContext attrName = (ConfigurableWebApplicationContext)wac;
                if(!attrName.isActive()) {
                    if(attrName.getParent() == null) {
                        attrName.setParent(rootContext);
                    }
                    this.configureAndRefreshWebApplicationContext(attrName);
                }
            }
        }
        if(wac == null) {
            wac = this.findWebApplicationContext();//通常返回的都是null
            //具體實現,獲取DispatcherServlet的applicationContext
            //WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext(), attrName);
        }
        if(wac == null) {
            wac = this.createWebApplicationContext(rootContext);
        }
        if(!this.refreshEventReceived) {
            this.onRefresh(wac);
        }
        if(this.publishContext) {
            //attrName1=org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher
            String attrName1 = this.getServletContextAttributeName();
            //新建立的容器上下文設置到ServletContext中
            this.getServletContext().setAttribute(attrName1, wac);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Published WebApplicationContext of servlet \'" + this.getServletName() + "\' as ServletContext attribute with name [" + attrName1 + "]");
            }
        }
        return wac;
    }

DispatcherServlet覆寫了FrameworkServlet中的onRefresh()方法,onRefresh()方法是鉤子方法,子類能夠重寫本身特有的方法。

protected void onRefresh(ApplicationContext context) { this.initStrategies(context); }

//初始化DispatcherServlet使用的策略
protected void initStrategies(ApplicationContext context) {
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
}

總結

ContextLoaderListener和DispatcherServlet均可以配置spring相關的XML,可是它們不是合併儲存的,而是父子關係,因此建議:mvc相關的spring配置由DispatcherServlet加載,而其他的JavaBean都交給ContextLoaderListener加載

相關文章
相關標籤/搜索