web-dev-qa-db-ja.com

ContextLoaderListenerかどうか?

標準のSpring Webアプリケーション(Rooまたは「Spring MVC Project」テンプレートで作成)は、ContextLoaderListenerおよびDispatcherServletを使用してweb.xmlを作成します。 なぜDispatcherServletを使用して完全な構成をロードするだけではないのですか?

私は、ContextLoaderListenerを使用してWebに関連しないものをロードし、DispatcherServletを使用してWebに関連するもの(コントローラーなど)をロードする必要があることを理解しています。そして、これは2つのコンテキストをもたらします:親と子のコンテキスト。

バックグラウンド:

私はこの標準的な方法を数年間行っていました。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Handles Spring requests -->
<servlet>
    <servlet-name>roo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

これにより、2つのコンテキストとそれらの間の依存関係に問題が発生することがよくありました。過去に私は常に解決策を見つけることができましたが、これによりソフトウェアの構造/アーキテクチャが常に改善されると強く感じています。しかし今、私は 両方のコンテキストのイベントの問題 に直面しています。

-しかし、これにより、この2つのコンテキストパターンを再考する必要があります。なぜこのトラブルに巻き込まれなければならないのか、1つのDispatcherServletですべてのスプリング構成ファイルをロードし、ContextLoaderListenerを完全に削除しないのはなぜですか? (別の構成ファイルを使用しますが、コンテキストは1つのみです。)

ContextLoaderListenerを削除しない理由はありますか?

122
Ralph

あなたの場合、いいえ、ContextLoaderListenerapplicationContext.xmlを保持する理由はありません。サーブレットのコンテキストだけでアプリが正常に機能する場合、それはそのままで、より簡単です。

はい、一般的に推奨されるパターンは、web以外のものをwebappレベルのコンテキストに保持することですが、それは単なる弱い慣習にすぎません。

Webappレベルのコンテキストを使用する唯一の説得力のある理由は次のとおりです。

  • サービスを共有する必要があるDispatcherServletが複数ある場合
  • Spring-wiredサービスへのアクセスを必要とするレガシー/非Springサーブレットがある場合
  • Webappレベルのコンテキストにフックするサーブレットフィルターがある場合(例:Spring SecurityのDelegatingFilterProxyOpenEntityManagerInViewFilterなど)

これらはどれも当てはまらないため、余分な複雑さは保証されません。

スケジュールされたタスク、JMS接続など、サーブレットのコンテキストにバックグラウンドタスクを追加するときは注意してください。<load-on-startup>web.xmlに追加するのを忘れると、これらのタスクは最初のサーブレットへのアクセス。

86
skaffman

Spring-MVCアプリケーションで行ったことを共有したい:

  1. we-mvc-config.xmlに、@ Controllerアノテーションが付けられたクラスのみを追加しました。

    <context:component-scan base-package="com.shunra.vcat">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
  2. applicationContext.xmlファイルに、残りすべてを追加しました。

    <context:component-scan base-package="com.shunra.vcat">
        <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
10
Modi

他の方法でアプリケーションコンテキストを構成することもできます。例えば。 OpenEntityManagerInViewFilterを機能させるため。 ContextLoaderListenerをセットアップしてから、DispatcherServletを次のように構成します。

<servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

contextConfigLocationパラメーター値が空であることを確認してください。

10
Gunnar Hillert