Spring MVCのソースコード解析(A):のContextLoaderListenerの設計と実装

ContextLoaderListener
私の春のソースコード解析では(A):TomcatなどのWebコンテナで分析しますが、この記事の春のソースを見始めるん、、、ウェブアプリケーションを起動するには、方法、通知のServletContextListener、Webコンテナは、Webを開始したリスナーを渡します適用される、のServletContextListenerは初期化ロジックをカスタマイズすることができます。ContextLoaderListenerのServletContextListenerは、デフォルト設定情報WEB-INF / applicationContext.xmlをファイルであるスプリング主容器関連豆をロードするための主な原因のインターフェースを実装するクラスです。


コンテナWebコンテナの中に春になるインタフェースを実装することでのContextLoaderListenerののServletContextListener。これは、二つの角度で理解することができます。
Webプロジェクト自体:WebApplicationContextを通じてBeanに関連する主なコンテナスプリング・プロジェクト、およびその他のコンポーネントを保護するために、Beanインスタンスを作成するためにロードされたのconfigure自体を解析を開始、通知WebコンテナのWebアプリケーションが起動されて受信します。
Webコンテナ:WebコンテナそれぞれのServletContextは、Webアプリケーションを維持、のContextLoaderListener Webコンテナとスプリング商品のServletContextを介して相互作用することができるようにWebApplicationContextは、のServletContextの属性として、キーは、のServletContextに格納されているばね容器。
 
以下の通りのContextLoaderListenerのみ関係スプリングコンテナとコンテナウェブを確立するための中間層として、実際の作業はのContextLoaderListenerが実装、論理上で定義されたContextLoaderに即ちContextLoader、によって実行される二つ以上の角度を完了する。
パッケージorg.springframework.web.context。
** 
 *ブートストラップリスナーが起動して、Springのルート{@link} WebApplicationContextをシャットダウンします。
 * 単純に委譲{@link ContextLoader}に対して同様{@link ContextCleanupListener}です。
 * 
 * <P>春3.1のように、{@codeのContextLoaderListener}は、ルートウェブ注入サポート
  *の{@link #ContextLoaderListener(WebApplicationContext)}を介してアプリケーション・コンテキストを
 許可する、*コンストラクタのためのサーブレット5.0+におけるプログラム構成環境。
 * {@link org.springframework.web.WebApplicationInitializer}を見るための使用例。
 * /
 パブリック クラスのContextLoaderListenerは拡張 ContextLoaderが実装のServletContextListener {
     / ** 
     *新しい{作成@code Webアプリケーションを作成するのContextLoaderListenerを} 
     *「contextClass」と「contextConfigLocation」サーブレットに基づくコンテキスト
     *コンテキストのparamsを。{参照してください@link の詳細については、ContextLoader}スーパークラスのドキュメント
     ごとに、*のデフォルト値を。
     * <P> {宣言する場合、このコンストラクタは、典型的に使用される@code のContextLoaderListener} 
     {よう* @code {以内<リスナー>} @code 引数なしのコンストラクタがあるのweb.xml}
     *要します。
     下* <P>作成されたアプリケーション・コンテキストは、のServletContextに登録する
     属性名{* @link WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE} 
     {とき*とSpringアプリケーションコンテキストが閉鎖され@link #contextDestroyed} 
     *ライフサイクルメソッドがこれに呼び出されますリスナー。
     * @see ContextLoader 
     * @see #ContextLoaderListener(WebApplicationContext)
     * @see #contextInitialized(ServletContextEvent)
     * @see #contextDestroyed(ServletContextEvent)
      * / 
    公共ContextLoaderListener(){ 
    } 
    / ** 
     *新しい{作成@code 所与のアプリケーション・コンテキストとのContextLoaderListenerを}。これは、
     *コンストラクタは、インスタンス・ベースのサーブレット3.0以降の環境で有用である
     *リスナーの登録が{によって可能である@link のjavax.servlet.ServletContext#のaddListener} 
     *のAPI。
     * <P>コンテキストまたはまだであってもなくてもよい{ @linkplain 
     (* org.springframework.context.ConfigurableApplicationContext番号リフレッシュ)リフレッシュ}。その場合
     *(A){実装で@link ConfigurableWebApplicationContext}と 
     *(B)の<strong> </ strong>の既に(推奨されるアプローチ)がリフレッシュされていない、
     *次いで、以下のことが発生する
     * <UL>
     * <LI>与えられたコンテキストが既に{割り当てられていない場合@linkplain 
     * org.springframework.context.ConfigurableApplicationContext#SETID ID}、一方がそれに割り当てられる</ LI> 
     * <LI> { @code用のServletContextを}と{ @code のServletConfig}オブジェクトはに委任する
     *アプリケーションのコンテキスト</ LI> 
     * <LI> { @link #customizeContext} </ LI>と呼ぶことにする
     任意{* <LI> @linkorg.springframework.context.ApplicationContextInitializer ApplicationContextInitializer org.springframework.context.ApplicationContextInitializer ApplicationContextInitializers} 
     "contextInitializerClasses" INIT-paramは適用されます。</ LI>によって指定* 
     * <LI> { @link org.springframework.context.ConfigurableApplicationContext#リフレッシュをリフレッシュ()} </ LI>と呼ぶことにする
     * </ UL> 
     コンテキストがすでに更新されているか、実装していない場合* 
     * { @code ConfigurableWebApplicationContext}を、上記のいずれも下生じない
     ユーザが持っている*仮定彼または彼女のあたりに(またはしない)これらのアクションを行っ
     *特定のニーズ。
     * <P>@link 使用例についてorg.springframework.web.WebApplicationInitializerを}。
     * <P>いずれの場合においても、
     *属性名{下のServletContext @link 
     * WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE}とSpring 
     {とき*アプリケーション・コンテキストは、閉鎖され@link #contextDestroyed}ライフサイクル
     ・メソッドは、このリスナに呼び出されます。
     * @paramを管理するためのコンテキストアプリケーションコンテキスト
      * / 
    公共のContextLoaderListener(WebApplicationContextコンテキスト){
         スーパー(コンテキスト)。
    } 
    / ** 
     *ルートWebアプリケーションのコンテキストを初期化します。
     * / 
    @Override 
    公共 のボイド contextInitialized(ServletContextEventイベント){
        initWebApplicationContext(event.getServletContext())。
    }     
    / ** 
     *ルートWebアプリケーションのコンテキストを閉じます。
     * / 
    @Override 
    公共 ボイドcontextDestroyed(ServletContextEventイベント){ 
        closeWebApplicationContext(event.getServletContext())。
        ContextCleanupListener.cleanupAttributes(event.getServletContext())。
    } 
}
ContextLoader
ApplicationContextのをルートスプリング一次容器を装填するための主な原因ContextLoaderは、設計レベルで主にCONTEXTID、contextConfigLocation、contextClass、contextInitializerClasses定義しました。これらのパラメータは、web.xmlコンテキスト-paramタグ、又はそれぞれベースのJavaプログラミングWebApplicationInitializerコンフィギュレーションモードの定義として、設定で指定することができます。
1.contextId:電流id容器、主として下地たBeanFactoryには、配列を利用して、使用されます。
 
2.contextConfigLocation:ロケーション・プロファイルは、デフォルトのWEB-INF / applicationContext.xmlをは、web.xmlのコンテキスト-paramタグを使用して別の場所を指定することができ、または他の名前はカンマで区切って複数指定します。設定ファイルでは豆でメインラベルとしてBeanを定義します。このような下地たBeanFactoryタグと、それによって収集BeanDefinitions、すなわち豆メタデータ・データベース・メモリを作成し、内部豆の豆を解決します。
 
3.contextClass:このような構成@などのアノテーションによって、等コンポーネント、@、basePackagesを走査することにより、AnnotationConfigWebApplicationContextある場合、それは、豆のWEB-INF / applicationContext.xmlを、次いでXmlWebApplicationContextとして使用に指定されている場合、現在、使用されるタイプWebApplicationContext指定されたパッケージは、Beanを作成します。
 
beanDefinition前ApplicationContextInitializer実装クラス、およびいくつかの初期化をWebApplicationContextするために、リフレッシュの呼び出しでロードされているのApplicationContext Beanを作成します4.contextInitializerClasses。

initWebApplicationContext:コンテナWebApplicationContext、完全に二つの主要なアクションに対応するメインスプリングを作成し、初期化します。

1. WebApplicationContextオブジェクトのインスタンスを作成し、リフレッシュ動作が指定された構成contextConfigLocation、負荷から終了し起動してBeanインスタンスのBeanDefinitionsを作成し、ソースコアは以下を達成します。
// ローカルコンテキストインスタンス変数に保管し、それはあなたを保証するために
 // ITシャットダウンのServletContextで提供されています。
IFをこの .context == nullの){ 

   // WebApplicationContext作成
    // これが指定contextClassを使用して指定された場合に特定のタイプを;
    // XmlWebApplicationContext 
   
    この .context = createWebApplicationContext(のServletContext); 
} 
IFこれは .context instanceofのConfigurableWebApplicationContext)を{ 
    ConfigurableWebApplicationContext CWAC =(ConfigurableWebApplicationContext)この.context。
    もし(!cwac.isActive()){ 
    
        // 设置親WebApplicationContext、
         // 对ルートWebApplicationContext来说、通常ヌル为
        
        // コンテキストがまだリフレッシュされていない- >などのサービスを提供する
         // 、親コンテキストを設定する設定アプリケーション・コンテキストID等
        場合(cwac.getParent()== NULL ){
             // コンテキストインスタンスは、明示的な親なしで注射した- >
             //は、もしあれば、ルートWebアプリケーションコンテキストの親を決定します。
            ApplicationContextの親= loadParentContext(のServletContext)。
            cwac.setParent(親)。
        }
        
        // コアメソッド、ロードコンフィギュレーションを完了するため、および作成BeanDefinition Beanオブジェクト定義
        configureAndRefreshWebApplicationContext(のServletContext CWAC)を; 
    } 
}

ApplicationContextのビーンコンテナを作成するためのリフレッシュ方法を、設定値ApplicationContextのプロファイルアドレスcontextConfigLocationを完了ApplicationContextInitializersを呼び出し、そして最終的に呼び出すための主な方法をconfigureAndRefreshWebApplicationContext。

保護された ボイドconfigureAndRefreshWebApplicationContext(ConfigurableWebApplicationContextのWAC、のServletContext SC){ 
        
        ... 
        
        wac.setServletContext(SC)。
        ストリングconfigLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM)。
        もし(!configLocationParam = ヌル){ 
            wac.setConfigLocation(configLocationParam)。
        } 

        // コンテキストときWAC環境の#initPropertySourcesは、どのような場合に呼び出されます
         。//がリフレッシュされます。サーブレットのプロパティソースはのための場所であることを確認するために熱心に、ここでそれを行う
         //いずれかの使用後の処理またはそれが#refresh前に初期の下に発生 
        ConfigurableEnvironment ENV = wac.getEnvironmentを();
         IF(ENV instanceofのConfigurableWebEnvironment){ 
            ((ConfigurableWebEnvironment)ENV).initPropertySources(SC、NULL ); 
        } 
        // ApplicationContextInitializerを使用ApplicationContextの初期化に
        customizeContext(SC、WAC); 
        
        // ApplicationContextのコアの方法:で開始ApplicationContextの完全なリフレッシュ処理
         // 例えばbeanDefinitionsとしてばねコンテナを作成するために、すなわち、それぞれのコア・コンポーネントを、enviromnet等
        
        wac.refresh(); 
    }

良いWebApplicationContext WebApplicationContextのインスタンスを作成する2.以下を達成するためのコア・ソース・コードのうちのServletContextに格納された属性として、良い例を作成します。

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE、この .context)。

:あるWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE

    / ** 
     *コンテキスト属性が正常に起動上にルートWebApplicationContextをバインドします。
     * <P>注:ルートコンテキストの起動に失敗した場合は、この属性に含めることができる
     値として*例外やエラーを。便利のためにWebApplicationContextUtilsを使用して
     、ルートWebApplicationContextの*検索。
     * @see org.springframework.web.context.support.WebApplicationContextUtils#getWebApplicationContext 
     * @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
      * / 
    文字列ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext。クラス .getName()+ ".ROOT"。
概要
上記の分析ショーを通じて、主要な血管の作成を完了するためにContextLoaderスプリング、仕事をするServletContextから責任があり、特にweb.xmlファイルまたはWebApplicationInitializerのServletContext実装クラスから、そのようcontextClassが指定使用などWebApplicationContext関連する構成情報を取得します達成WebApplicationContext種は、contextConfigLocationはWebApplicationContextInitializersは、再処理のためWebApplicationContextの春を行う前にコンテナを作成するために取得し、春のコンテナの設定ファイルを指定しました。
作成した春のコンテナは、コンフィギュレーションから定義取得豆を完了し、BeanDefinitionを作成し、いくつかのリソースの属性値を取得するには、スプリング・コンテキストパッケージのApplicationContext、たBeanFactory春豆のパッケージの使用、で、単一の実施形態Beanの完了は次のように作成します。特定の記事のApplicationContextとたBeanFactoryアーキテクチャでの分析の後。
 
より教材のために、グループに追加することができる:473 984 645またはFangerウェイコードスキャンの下

おすすめ

転載: www.cnblogs.com/1013wang/p/11763049.html