spring-mvc源碼-上下文的初始化

 

1、總覽

目錄

1、總覽

2、根上下文初始化


   spring-mvc項目裏一般會有兩個上下文,一個是根上下文(Root WebApplicationContext),一個是spring mvc上下文(Servlet WebApplicationContext,可以有多個),那麼爲什麼要存在這兩種上下文,可以看下官方的解釋。

DispatcherServlet expects a WebApplicationContext (an extension of a plain ApplicationContext) for its own configuration. WebApplicationContext has a link to the ServletContext and the Servlet with which it is associated. It is also bound to the ServletContext such that applications can use static methods on RequestContextUtils to look up theWebApplicationContext if they need access to it.

For many applications, having a single WebApplicationContext is simple and suffices. It is also possible to have a context hierarchy where one root WebApplicationContext is shared across multiple DispatcherServlet (or other Servlet) instances, each with its own child WebApplicationContext configuration.

The root WebApplicationContext typically contains infrastructure beans, such as data repositories and business services that need to be shared across multiple Servlet instances. Those beans are effectively inherited and can be overridden (that is, re-declared) in the Servlet-specific child WebApplicationContext, which typically contains beans local to the given Servlet.

 

大概意思是:

DispatcherServlet需要一個上下文用於其自身配置。這個上下文具有到ServletContext及其關聯的Servlet的鏈接。它也綁定到ServletContext,這樣應用程序就可以使用RequestContextUtils的靜態方法訪問這個上下文。

對於許多應用程序來說,擁有一個上下文是簡單和足夠的。但也可以有一個層次結構的上下文,其中一個根上下文在多個DispatcherServlet(或其他Servlet)實例中共享,每個實例也都有自己的上下文配置。

根上下文通常包含基礎bean,例如需要跨多個Servlet實例共享的數據庫和業務服務。這些bean是可以繼承的,可以在子上下文中重寫(即重新定義),子上下文通常包含當前Servlet的本地bean。

層次結構如下:

  • Servlet WebApplicationContext:這是對J2EE三層架構中的web層進行配置,如控制器(controller)、視圖解析器(view resolvers)等相關的bean。通過spring mvc中提供的DispatchServlet來加載配置,通常情況下,配置文件的名稱爲spring-mvc.xml。
  • Root WebApplicationContext:這是對J2EE三層架構中的service層、dao層進行配置,如業務bean,數據源(DataSource)等。通常情況下,配置文件的名稱爲applicationContext.xml。在web應用中,其一般通過ContextLoaderListener來加載。

這兩個上下文,都是在容器啓動的過程中初始化的,那麼容器是怎麼知道他們的呢,我們知道web容器的初始化首先是加載web.xml文件,並且對其中定義的listener和servlet等進行相應的加載和初始化。那麼我們可以自定義一個listener(ContextLoaderListener)或servlet(DispatcherServlet),容器會根據web.xml加載和初始化他們,而他們則負責加載相應的配置文件。

在web.xml配置文件中,有兩個主要的配置:ContextLoaderListener和DispatcherServlet。同樣的關於spring配置文件的相關配置也有兩部分:context-param和DispatcherServlet中的init-param。那麼,這兩部分的分別表示是Spring 容器的初始化和web容器的初始化。DispatcherServlet和ContextLoaderListener提供了在Web容器中對spring的接口。ServletContext爲Spring的IOC容器提供了一個宿主環境,在宿主環境中,Spring MVC建立起了一個IOC容器體系。

看下web.xml的配置:

<web-app>

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

    <!—創建Root WebApplicationContext-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-context.xml</param-value>
    </context-param>

    <!—創建Servlet WebApplicationContext-->
    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>

</web-app>

2、根上下文初始化

 Spring Framework本身沒有Web功能,Spring MVC使用WebApplicationContext接口擴展ApplicationContext,使得擁有web功能,WebApplicationContext接口默認的實現是XmlWebApplicationContext。那麼,Spring MVC是如何在web環境中創建IoC容器呢?先看一下WebApplicationContext的源碼:

public interface WebApplicationContext extends ApplicationContext {

	//用於在ServletContext中存取根上下文
	String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

	String SCOPE_REQUEST = "request";

	String SCOPE_SESSION = "session";

	String SCOPE_GLOBAL_SESSION = "globalSession";

	String SCOPE_APPLICATION = "application";

	String SERVLET_CONTEXT_BEAN_NAME = "servletContext";

	String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";

	String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";

	//取得當前web容器的ServletContext
	ServletContext getServletContext();

}

未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章