Spring的雙親上下文機制

小胡哥哥發表於2018-10-31

Spring中的ApplicationContext是父子層次結構的,在存在多個上下文時,會有一個根上下文,作為其他上下文的“父親”。:

<Listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
複製程式碼

如上,如果在web.xml檔案中使用Listener監聽器來載入Spring的配置,Spring會建立一個全域性的WebApplicationContext上下文,此上下文被稱為根上下文,儲存在ServletContext中。

public interface WebApplicationContext extends ApplicationContext {

	/**
	 * Context attribute to bind root WebApplicationContext to on successful startup.
	 * <p>Note: If the startup of the root context fails, this attribute can contain
	 * an exception or error as value. Use WebApplicationContextUtils for convenient
	 * lookup of the root WebApplicationContext.
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#getWebApplicationContext
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
	 */
	String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

	/**
	 * Scope identifier for request scope: "request".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_REQUEST = "request";

	/**
	 * Scope identifier for session scope: "session".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_SESSION = "session";

	/**
	 * Scope identifier for global session scope: "globalSession".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_GLOBAL_SESSION = "globalSession";

	/**
	 * Scope identifier for the global web application scope: "application".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_APPLICATION = "application";

	/**
	 * Name of the ServletContext environment bean in the factory.
	 * @see javax.servlet.ServletContext
	 */
	String SERVLET_CONTEXT_BEAN_NAME = "servletContext";

	/**
	 * Name of the ServletContext/PortletContext init-params environment bean in the factory.
	 * <p>Note: Possibly merged with ServletConfig/PortletConfig parameters.
	 * ServletConfig parameters override ServletContext parameters of the same name.
	 * @see javax.servlet.ServletContext#getInitParameterNames()
	 * @see javax.servlet.ServletContext#getInitParameter(String)
	 * @see javax.servlet.ServletConfig#getInitParameterNames()
	 * @see javax.servlet.ServletConfig#getInitParameter(String)
	 */
	String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";

	/**
	 * Name of the ServletContext/PortletContext attributes environment bean in the factory.
	 * @see javax.servlet.ServletContext#getAttributeNames()
	 * @see javax.servlet.ServletContext#getAttribute(String)
	 */
	String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";


	/**
	 * Return the standard Servlet API ServletContext for this application.
	 * <p>Also available for a Portlet application, in addition to the PortletContext.
	 */
	ServletContext getServletContext();

}
複製程式碼

其中,key為org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUT屬性的值。 在很多情況下,我們還會配置一個或者多個DispatcherServlet,每個DispatcherServlet都有一個自己的WebApplicationContext上下文。這個上下文是私有的,繼承了根上下文的所有內容,該上下文儲存在ServletContext中,key是org.springframework.web.servlet.FrameworkServlet#SERVLET_CONTEXT_PREFIX的值+servlet名稱。當一個Request物件產生時,會把這個WebApplicationContext上下文儲存在Request物件中。

為了避免雙親上下文,可以不使用Listener監聽器載入Spring配置,直接使用DispatcherServlet載入Srping配置。

摘自《Java工程師修煉之道》

相關文章