エントリからソースコード分析トピック2_tomcatまでのSpringmvcサービスの起動時にContextLoaderListenerをロードする方法
序文
前回の記事では、関連する準備を行い、プロジェクト環境をセットアップし、最初のspringmvcプロジェクトhellowordを正常に実行しましたが、構成ファイルの構成を詳しく説明して分析しませんでした。この記事と後続の記事では、これらの構成の役割を分析して説明し、ソースコードを調べて、これらの構成がどのように実装されているかを説明します。
ServletContextの役割
-
ServletContext
後で分析するためorg.springframework.web.context.ContextLoaderListener
に非常に重要であるため、最初に役割について説明します。 -
ServletContextは、情報のグローバルストレージスペースです。サーバーが起動すると存在し、サーバーがシャットダウンすると解放されます。リクエスト、ユーザーは複数、セッション、1人のユーザー、servletContext、すべてのユーザーが1つを共有できます。したがって、スペースを節約して効率を向上させるために、ServletContextには、必要で、重要で、すべてのユーザーが共有し、安全な情報を入力する必要があります。
-
Webコンテナーを開始した後、Webコンテナーはweb.xmlの構成情報を読み取り、ServletContextを補足します。(注:構成のロード順序は、context-param->リスナー->フィルター->サーブレットです)
ServletContextListenerの役割
ServletContextListenerは、ServletContextのライフサイクルの変更に関する通知イベントを受信するために使用されるインターフェースであるServletContextのリスナーです。ServletContextの変更を監視します。たとえば、サーバーの起動時にServletContextが作成され、サーバーのシャットダウン時にServletContextが破棄されます。
ContextLoaderListenerのソースコード分析
- まず、web.xmlで構成する方法を見てみましょう。
org.springframework.web.context.ContextLoaderListener
<!-- 使用ContextLoaderListener配置时,需要告诉它Spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--
配置上下文载入器,上下文载入器载入除DispatherServlet载入的配置文件之外的其他上下文配置文件
最常用的上下文载入器是一个Servlet监听器,器名称为ContextLoaderListener
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- ContextLoaderListenerのソースコード
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
private ContextLoader contextLoader;
...
/**
* Initialize the root web application context.
*/
public void contextInitialized(ServletContextEvent event) {
this.contextLoader = createContextLoader();
if (this.contextLoader == null) {
this.contextLoader = this;
}
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
protected ContextLoader createContextLoader() {
return null;
}
...
}
-
より
ContextLoaderListener
ソース、我々はそれが実装されていることがわかりServletContextListener
、コンテナによって開始されたプロセスを呼び出すためにバインドされ、インターフェイス、ContextLoaderListener#contextInitialized(...)
コンテナが閉じられたときに呼び出されるメソッドを、ContextLoaderListener#contextDestroyed(...)
方法は -
では
ContextLoaderListener#contextInitialized(...)
、メソッドの主な機能は何ですか?その主な機能は初期化WebApplicationContext
です。メソッドで呼び出されたinitWebApplicationContext(...)
メソッドのコメントから、どのように実行されているかがわかりますか?見下ろし続けましょう -
ContextLoader#initWebApplicationContext(...)
コードスニペット
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!");
}
...
try {
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
...
// 配置并刷新WebApplicationContext
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
configureAndRefreshWebApplicationContext(cwac, servletContext);
...
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
...
return this.context;
}catch (RuntimeException ex) {
...
}
ContextLoader#createWebApplicationContext(...)
コードスニペット
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
//获取 org.springframework.web.context.support.XmlWebApplicationContext 的class
Class<?> contextClass = determineContextClass(sc);
...
//通过反射创建WebApplicationContext对象
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
-
では
ContextLoader#initWebApplicationContext(...)
、最初にservletContextに存在するかどうかを判断し、存在する場合WebApplicationContext
は例外をスローしてから、オブジェクトが空かどうかを判断します。プログラムを初めて実行するときは、オブジェクトは空です。次に、を呼び出してオブジェクトをContextLoader#createWebApplicationContext(...)
作成しWebApplicationContext
ます。次に、ContextLoader#configureAndRefreshWebApplicationContext(...)
メソッド構成を呼び出し、WebApplicationContextコンテキストを更新します -
ContextLoader#configureAndRefreshWebApplicationContext(...)
メソッドコードスニペット
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
...
//将ServletContext对象保存到上下文中
wac.setServletContext(sc);
//获取web.xml中配置的contextConfigLocation的值
String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocationParam != null) {
wac.setConfigLocation(configLocationParam);
}
....
// 刷新WebApplicationContext上下文
wac.refresh();
}
- 次のステップは、ある
WebApplicationContext
オブジェクトに設定されservletContext
、簡単に後で使用これはあるorg.springframework.web.context.ContextLoaderListener
の役割
総括する
上記の分析を通じて、org.springframework.web.context.ContextLoaderListener
役割がweb.xmlでcontextConfigLocation
指定したSpring Bean構成ファイルをロードしてルートWebApplicationContextコンテキストを作成することであることを確認するのは難しくありません。わかりました。この記事はここにあります。次の記事では、コンテナの起動プロセスorg.springframework.web.servlet.DispatcherServlet
はどのように実行されますか