Webアプリケーションの場合、ServletContextオブジェクトは一意です。Webアプリケーションには、Webアプリケーションのロード時に初期化されるServletContextオブジェクトが1つだけあります。ServletContextの初期化時にSpringコンテナーの作成時刻を設定すると、Springコンテナーの作成が1回だけ実行されることが保証され、アプリケーション全体でのSpringコンテナーの一意性も保証されます。
Springコンテナーが作成された後、Springコンテナーは、アプリケーションのライフサイクル全体を通じていつでもアクセスできる必要があります。つまり、Springコンテナはグローバルである必要があります。ServletContextオブジェクトに配置される属性は、アプリケーションのグローバルな性質を持っています。したがって、作成されたSpringコンテナーを属性の形式でServletContextスペースに配置すると、Springコンテナーのグローバル性が保証されます。
上記の作業は、SpringのJarパッケージの関連APIに次のようにカプセル化されています:spring-web-5.2.5.RELEASE
以下に使用手順を示します
pom.xmlファイルに依存関係を追加します
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
web.xmlファイルにリスナーを登録します
ServletContextの初期化時にSpringコンテナを作成するには、リスナーインターフェイスServletContextListenerを使用してServletContextを監視する必要があります。web.xmlにリスナーを登録します
Springは、リスナーインターフェイスの実装クラスContextLoaderListenerを定義します。これは、コンテナオブジェクトの作成とコンテナオブジェクトのServletContextスペースへの配置という2つの非常に重要なタスクを実行します。ContextLoaderListenerのソースコードを開きます。合計4つのメソッドがあり、そのうちの2つは構築メソッド、1つは初期化メソッド、1つは破棄メソッドです。
<!--注册监听器 ContextLoaderListener-->
<!--
监听器被创建对象后,会读取/WEB-INF/applicationContext.xml
可以修改默认的文件位置,使用context-param重新指定文件位置
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
try {
if (this.context == null) {
this.context = this.createWebApplicationContext(servletContext);
}
if (this.context instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
if (!cwac.isActive()) {
if (cwac.getParent() == null) {
ApplicationContext parent = this.loadParentContext(servletContext);
cwac.setParent(parent);
}
this.configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
上記はinitWebApplicationContext()メソッドのソースコードの一部です。コンテナオブジェクトコンテキストがこのメソッドで作成され、コンテキストオブジェクトがservletContextグローバルスコープオブジェクトに追加されていることがわかります。キー値はWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTEです。
コンテナオブジェクトを取得します
1.キー値から直接取得します
WebApplicationContext context = null;
Object attr = getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (attr != null){
context = (WebApplicationContext)attr;
}
2.WebApplicationContextUtilsツールクラスを介して取得
以下は、WebApplicationContextUtilsの呼び出し関係を明確に取得できることです。
public static WebApplicationContext getRequiredWebApplicationContext(ServletContext sc) throws IllegalStateException {
WebApplicationContext wac = getWebApplicationContext(sc);
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
} else {
return wac;
}
}
@Nullable
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
@Nullable
public static WebApplicationContext getWebApplicationContext(ServletContext sc, String attrName) {
Assert.notNull(sc, "ServletContext must not be null");
Object attr = sc.getAttribute(attrName);
ServletContext sc = getServletContext();
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(sc);