SpringでのContextLoaderListenerの役割/目的?


169

私のプロジェクトで使用されているSpring Frameworkを学習しています。web.xmlファイルでContextLoaderListenerエントリを見つけました 。しかし、それが開発者にどれだけ役立つかを理解できませんでしたか?

ContextLoaderListenerの公式ドキュメントには、WebApplicationContextを起動するように記載されています。WebApplicationContextについてJavaDocsは言う:

Webアプリケーションの構成を提供するインターフェース。


しかし、WebApplicationContextを内部的に初期化するContextLoaderListenerで何を達成しているのか理解できません。

私の理解よる と、ContextLoaderListenerはSpring構成ファイル(web.xmlの contextConfigLocationに対して指定された値を使用)を読み取り、それを解析して、その構成ファイルで定義されているシングルトンBeanをロードします。同様に、プロトタイプBeanをロードする場合は、同じWebアプリケーションコンテキストを使用してBeanをロードします。したがって、事前に構成ファイルを読み取り/解析/検証するようにContextLoaderListenerを使用してWebアプリケーションを初期化し、依存関係を挿入したいときはいつでも、遅延なくすぐに実行できます。この理解は正しいですか?


1
缶誰も私がRequestContextListenerとのContextLoaderListenerの違いを知っている
VdeX

回答:


111

あなたの理解は正しいです。ApplicationContextあなたの春の豆が住んでいる場所です。の目的ContextLoaderListenerは2つあります。

  1. ライフサイクルを結びつけるためApplicationContextのライフサイクルにServletContextし、

  2. の作成を自動化するApplicationContextため、それを作成するために明示的なコードを記述する必要はありません。これは便利な関数です。

もう一つの便利な事はContextLoaderListener、それが作成することですWebApplicationContextし、WebApplicationContextへのアクセスを提供ServletContext介して、ServletContextAware豆とgetServletContext方法。


2
2つ目の点について疑問があります。ServletContextListenerはServletContextへのアクセスを提供すると言っていました。ただし、web.xmlにServletContextListenerがない場合でも、WebApplicationContextを介してServletContextにアクセスできます(WebApplicationContextは自動接続されます)。それで、それは正確にServletContextに関連して何をしますか?
Sumit Desai 2013

を作成しWebApplicationContextます。それ以外の場合は、手動で作成する必要があります。
sourcedelica 2013

ないContextLoaderListener時にWebコンテナシャットダウンして、すべての豆を破壊するために破壊する方法を実装しますか?
2013

はい- contextDestroyed呼び出されたときにそれを行います。APIドキュメントをご覧ください。
sourcedelica 2013

@sourcedelicaこれを読んだ後、アプリケーションをチェックしましたweb.xml。私のxmlファイルには、2つのリスナーContextLoaderListenerとがありDispatcherServletます。したがって、両方の必要はないと思いContextLoaderListenerます。アプリケーションが7〜8か月間生きているので、なぜ私が尋ねているのかを削除しても安全です。web.xmlがあるここにあなたの参考のために。
Amogh 2017

43

ContextLoaderListenerあるオプション。ここで強調しておきます。Springアプリケーションは、を設定しなくても起動できます。ContextLoaderListener基本的な最小要件web.xmlDispatcherServletです。

これは次のようになります。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" 
    version="2.5">
  <display-name>Some Minimal Webapp</display-name>
  <welcome-file-list>   
    <welcome-file>index.jsp</welcome-file>    
  </welcome-file-list>

  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

ファイルを作成dispatcher-servlet.xmlし、下に保管WEB-INF。私たちが言及したのでindex.jsp歓迎リストで、下にこのファイルを追加しますWEB-INF

dispatcher-servlet.xml

ではdispatcher-servlet.xml、あなたの豆を定義します。

<?xml version="1.0" encoding="UTF-8"?>
<beans 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd     
        http://www.springframework.org/schema/context     
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="bean1">
      ...
    </bean>
    <bean id="bean2">
      ...
    </bean>         

    <context:component-scan base-package="com.example" />
    <!-- Import your other configuration files too -->
    <import resource="other-configs.xml"/>
    <import resource="some-other-config.xml"/>

    <!-- View Resolver -->
    <bean 
        id="viewResolver" 
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
      <property 
          name="viewClass" 
          value="org.springframework.web.servlet.view.JstlView" />
      <property name="prefix" value="/WEB-INF/jsp/" />
      <property name="suffix" value=".jsp" />
    </bean>
</beans>

2
それはオプションだ場合は、ときになりたい、それを使用しますか?Spring SecurityではDelegatingFilterProxyを使用する必要があるようです。
デビッド

6
デフォルトの名前「[servlet-name] -servlet.xml」と「Web-INF /」の下のパスではなく、カスタムの場所またはカスタム名でサーブレットファイルを配置する場合は、これを使用する必要があります
Ramesh Karna

applicationContext.xmlよりもdispatcher-servlet.xmlでBeanを定義することは良い考えですか?
Chetan Gole、2015年

8
通常、アプリケーションのアーキテクチャーのレイヤーを反映してBeanを配布することをお勧めします。プレゼンテーション層(mvcコントローラーなど)のBeanは、dispatcher-servlet.xmlに含めることができます。サービス層に属するBeanは、applicationContext.xmlで定義する必要があります。これは厳密なルールではありませんが、関心の分離を実現することは良い習慣です。
Claudio Venturini、2015年

2
@Ramesh Karna名前と場所の変更には必要ないと思います。複数のDispatcherサーブレットを初期化していて、ルートコンテキストをすべてのDispaterServlets独自のコンテキストで共有したい場合は、ContextLoaderListenerを使用する必要があると思います。
超新星

23

シンプルなSpringアプリケーションのために、あなたが定義する必要はありませんContextLoaderListener、あなたにweb.xml。すべてのSpring構成ファイルを<servlet>次の場所に置くことができます:

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/mvc-core-config.xml, classpath:spring/business-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

複数のDispatcherServlet定義が存在する、より複雑なSpringアプリケーションの場合、共通のSpring構成ファイルを、でDispatcherServlet定義されたすべての定義で共有できますContextLoaderListener

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/common-config.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>mvc1</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/mvc1-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
    <servlet-name>mvc2</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/mvc2-config.xmll</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

ルートアプリケーションコンテキストのContextLoaderListener実際の初期化作業を実行することに注意してください。

この記事が非常に役立つことがわかりました: Spring MVC –アプリケーションコンテキストとWebアプリケーションコンテキスト


ここで共有された記事は、概念の深い理解を実際に保証します
Priyank Thakkar 2017年

10

ブログ「ContextLoaderListenerの目的– Spring MVC」は、非常に良い説明を提供しています。

それによると、Application-Contextsは階層的であり、したがってDispatcherSerlvetのコンテキストはContextLoaderListenerのコンテキストの子になります。そのため、コントローラーレイヤー(StrutsまたはSpring MVC)で使用されているテクノロジは、ルートコンテキストで作成されたContextLoaderListenerから独立できます。


バディを共有してくれてありがとう.. :)
Deepak Kumar

3

[servletname]-servlet.xml下のデフォルトの命名規則とパスではなく、カスタムの場所またはカスタム名でサーブレットファイルを配置するWeb-INF/場合は、を使用できますContextLoaderListener


3

ContextLoaderListnerは、すべての異なる構成ファイル(サービスレイヤー構成、永続性レイヤー構成など)を単一のSpringアプリケーションコンテキストにロードするサーブレットリスナーです。

これにより、Spring構成を複数のXMLファイルに分割できます。

コンテキストファイルが読み込まれると、SpringはBean定義に基づいてWebApplicationContextオブジェクトを作成し、それをWebアプリケーションのServletContextに格納します。


3

ここに画像の説明を入力してくださいこのBootstrapリスナーは、Springのルート WebApplicationContext を起動およびシャットダウンします。Webアプリケーションは複数のディスパッチャーサーブレットを持つことができ、それぞれがコントローラー、ビューリゾルバー、ハンドラーマッピングなどを含む独自のアプリケーションコンテキストを持つことができますが、サービスBean、DAO Beanをルートアプリケーションコンテキストに置き、すべての子アプリケーションコンテキストで使用したい場合があります(ディスパッチャサーブレットによって作成されたアプリケーションコンテキスト)。

このリスナーの2番目の用途は、Spring Securityを使用する場合です。


3

ルートと子のコンテキストさらに読む前に、次のことを理解してください–

Springは一度に複数のコンテキストを持つことができます。それらの1つはルートコンテキストになり、他のすべてのコンテキストは子コンテキストになります。

すべての子コンテキストは、ルートコンテキストで定義されたBeanにアクセスできます。しかし、反対は真実ではありません。ルートコンテキストは子コンテキストBeanにアクセスできません。

ApplicationContext:

applicationContext.xmlは、すべてのWebアプリケーションのルートコンテキスト構成です。SpringはapplicationContext.xmlファイルをロードし、アプリケーション全体のApplicationContextを作成します。Webアプリケーションごとに1つのアプリケーションコンテキストのみが存在します。contextConfigLocationパラメーターを使用してweb.xmlでコンテキスト構成ファイル名を明示的に宣言していない場合、SpringはWEB-INFフォルダーでapplicationContext.xmlを検索し、このファイルが見つからない場合はFileNotFoundExceptionをスローします。

ContextLoaderListenerルートアプリケーションコンテキストの実際の初期化作業を実行します。「contextConfigLocation」context-paramを読み取り、その値をコンテキストインスタンスに渡して、任意の数のコンマとスペースで区切られる可能性のある複数のファイルパスに解析します。例:「WEB-INF / applicationContext1.xml、WEB-INF / applicationContext2.xml」。ContextLoaderListenerはオプションです。ここで強調しておきたいのは、ContextLoaderListenerを構成しなくても、DispatcherServletを使用した基本的な最小限のweb.xmlでSpringアプリケーションを起動できることです。

DispatcherServlet DispatcherServletは基本的にサーブレット(HttpServletを拡張したもの)であり、その主な目的は、構成されたURLパターンに一致する着信Webリクエストを処理することです。着信URIを受け取り、コントローラーとビューの正しい組み合わせを見つけます。それがフロントコントローラーです。

Spring構成でDispatcherServletを定義するときは、contextConfigLocation属性を使用して、コントローラークラスのエントリ、ビューのマッピングなどをXMLファイルに提供します。

WebApplicationContext ApplicationContextとは別に、1つのWebアプリケーションに複数のWebApplicationContextを含めることができます。簡単に言うと、各DispatcherServletは単一のWebApplicationContextに関連付けられています。xxx-servlet.xmlファイルはDispatcherServletに固有であり、Webアプリケーションは複数のDispatcherServletを構成してリクエストを処理できます。このようなシナリオでは、各DispatcherServletに個別のxxx-servlet.xmlが構成されます。ただし、applicationContext.xmlはすべてのサーブレット構成ファイルに共通です。Springはデフォルトで、「xxx-servlet.xml」という名前のファイルをwebapps WEB-INFフォルダーからロードします。xxxはweb.xmlのサーブレット名です。そのファイル名の名前または場所を変更する場合は、パラメーター名としてcontextConfigLocationを含むiniti-paramを追加します。

それらの間の比較と関係:

ContextLoaderListenerとDispatcherServlet

ContextLoaderListenerは、ルートアプリケーションコンテキストを作成します。DispatcherServletエントリは、サーブレットエントリごとに1つの子アプリケーションコンテキストを作成します。子コンテキストは、ルートコンテキストで定義されたBeanにアクセスできます。ルートコンテキストのBeanは、子コンテキストのBeanに(直接)アクセスできません。すべてのコンテキストがServletContextに追加されます。WebApplicationContextUtilsクラスを使用してルートコンテキストにアクセスできます。

Springのドキュメントを読んだ後、次のことが理解できます。

a)Application-Contextsは階層的であり、WebApplicationContextsも同様です。こちらのドキュメントを参照してください。

b)ContextLoaderListenerは、WebアプリケーションのルートWebアプリケーションコンテキストを作成し、それをServletContextに配置します。このコンテキストを使用して、コントローラー層(StrutsまたはSpring MVC)で使用されているテクノロジーに関係なく、Spring管理のBeanをロードおよびアンロードできます。

c)DispatcherServletは独自のWebApplicationContextを作成し、handlers / controllers / view-resolversはこのコンテキストによって管理されます。

d)ContextLoaderListenerがDispatcherServletと組み合わせて使用​​される場合、前述のようにルートweb-application-contextが最初に作成され、子コンテキストもDispatcherSerlvetによって作成され、ルートapplication-contextにアタッチされます。こちらのドキュメントを参照してください。

Spring MVCを使用していて、サービスレイヤーでSpringも使用している場合、2つのアプリケーションコンテキストを提供します。1つ目はContextLoaderListenerを使用して構成され、もう1つはDispatcherServletを使用して構成されます。

一般に、DispatcherServletコンテキストですべてのMVC関連Bean(コントローラーやビューなど)を定義し、ContextLoaderListenerによってルートコンテキストでセキュリティ、トランザクション、サービスなどのすべてのクロスカッティングBeanを定義します。

詳細については、こちらを参照してください:https : //siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html


2

基本的に、ContextLoaderListnerを使用して、ルートアプリケーションコンテキストとWebアプリケーションコンテキストを分離できます。

context paramでマップされた構成ファイルは、ルートアプリケーションコンテキスト構成として動作します。また、ディスパッチャーサーブレットでマップされた構成ファイルは、Webアプリケーションコンテキストのように動作します。

どのWebアプリケーションでも、複数のディスパッチャーサーブレットが存在する可能性があるため、複数のWebアプリケーションコンテキストがあります。

ただし、どのWebアプリケーションでも、すべてのWebアプリケーションコンテキストで共有されるルートアプリケーションコンテキストは1つだけです。

共通のサービス、エンティティ、アスペクトなどをルートアプリケーションコンテキストで定義する必要があります。また、コントローラー、インターセプターなどは、関連するWebアプリケーションのコンテキストにあります。

サンプルのweb.xmlは

<!-- language: xml -->
<web-app>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>example.config.AppConfig</param-value>
    </context-param>
    <servlet>
        <servlet-name>restEntryPoint</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>example.config.RestConfig</param-value>
        </init-param>       
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>restEntryPoint</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>webEntryPoint</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>example.config.WebConfig</param-value>
        </init-param>       
        <load-on-startup>1</load-on-startup>
    </servlet>  
    <servlet-mapping>
        <servlet-name>webEntryPoint</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app> 

ここで構成クラスexample.config.AppConfigを使用して、他のすべてのWebアプリケーションコンテキストと共有されるルートアプリケーションコンテキストでサービス、エンティティ、アスペクトなどを構成できます(たとえば、ここでは2つのWebアプリケーションコンテキスト構成クラスRestConfigとWebConfigがあります)

PS:ContextLoaderListenerは完全にオプションです。ここでweb.xmlのContextLoaderListenerについて触れない場合、AppConfigは機能しません。その場合、すべてのサービスとエンティティをWebConfigとRest Configで構成する必要があります。


1

Webアプリケーションのデプロイ時に実行したいコードを配置するためのフックポイントを提供します


Jigar、これは実際に私が見つけようとしていることです。機能とは何ですか。デフォルトのコンテキストローダークラスは、デプロイメント時に提供しますか?
M Sach

プロパティ/ xmlファイルを変更し、サーバーを再起動せずに実行時にそれらを再読み込みできるようにする
vsingh

1

リスナークラス-イベントをリッスンします(例:サーバーの起動/シャットダウン)

ContextLoaderListener-

  1. サーバーの起動/シャットダウン時にリッスンします
  2. Spring構成ファイルを入力として受け取り、構成に従ってBeanを作成して準備をします(シャットダウン時にBeanを破棄します)
  3. 構成ファイルは、web.xmlでこのように提供できます

    <param-name>contextConfigLocation</param-name>  
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>  

1

Spring Frameworkのコンテキストでは、ContextLoaderListenerの目的は、アプリケーションのバックエンドを駆動する中間層およびデータ層コンポーネントなど、アプリケーション内の他のBeanをロードすることです。


0

あなたの理解は正しいです。なぜContextLoaderListenerにメリットが見られないのでしょうか。たとえば、(データベースを管理するために)セッションファクトリを構築する必要があります。この操作には時間がかかる場合があるため、起動時に実行することをお勧めします。もちろん、initサーブレットなどでそれを行うことができますが、Springのアプローチの利点は、コードを記述せずに構成を作成できることです。


0

ContextLoaderListenerなしでweb.xmlを記述する場合、春のセキュリティでcustomAuthenticationProviderを使用してathunticationを与えることはできません。DispatcherServeletはContextLoaderListenerの子コンテキストであるため、customAuthenticationProviderは、ContextLoaderListenerであるparentContextの一部です。したがって、親コンテキストは子コンテキストの依存関係を持つことができません。したがって、initparamではなく、contextparamにspring-context.xmlを書き込むことをお勧めします。


0

複数の設定ファイルが必要な場合や、例えばapplicationcontext.xmlの代わりにxyz.xmlファイルがある場合に、実際に使用すると思います。

<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>

ContextLoaderListenerへの別のアプローチは、以下のようなContextLoaderServletを使用することです

<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.