web-dev-qa-db-ja.com

Spring Servletプロジェクトのweb.xmlでcontextConfigLocationをロードする順序

Spring Javaプロジェクトがあり、Webサーバーサーブレットとして設定しようとしているとします。以下は、web.xmlファイルの簡略版です。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/generalApplicationContext.xml
    </param-value>
</context-param>

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/foo/*</url-pattern>
</servlet-mapping>

ここで重要なことは、ロードする2つのXMLファイルを指定したことです。 1つはアプリケーション全体に一般的なもので、もう1つは「my-servlet」サーブレットに固有のものです。サーブレットマッピングが1つだけのセットアップでは、これは意味がありません。ただし、私のプロジェクトには複数のサーブレットマッピングがあり、それぞれに特定のSpring設定があります。

私の質問: Springによって最初にロードされるcontextConfigLocationはどれですか? generalApplicationContext.xmlになりますか、それともspecificApplicationContext.xmlになりますか?さらに重要なことは、ロードの順序も重要なのでしょうか?私のデバッグの努力から、あるファイルから別のファイルにいくつかの独立したSpring構成を移動すると、異なるエラーが発生するため、それが明らかになるようです。

NB:複数のサーブレットマッピングに複数のスプリングコンフィグレーションを使用することが良い習慣であるかどうかは議論の余地があります。同じことは、新しいJava config。の代わりにXML configを使用する場合にも当てはまります。しかし、これは私がここで尋ねようとしているものではありません。

17
ecbrodie

generalApplicationContext.xmlは、ApplicationContextとともにロードされるContextLoaderListenerであるため、最初にロードされるものです。

<listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/generalApplicationContext.xml
    </param-value>
</context-param>

specificApplicationContext.xmlは、実際にはロードされた上記の子コンテキストですgeneralApplicationContext.xmlそしてそれはWebApplicationContextになります

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>my-servlet</servlet-name>
    <url-pattern>/foo/*</url-pattern>
</servlet-mapping>

はい、ロードの順序は重要です。親コンテキストがロードされると、必要な依存関係がすべて満たされる必要があるためです。

21
shazin

以下の部分は、コンテキストファイルをロードし、ApplicationContextを作成します。たとえば、このコンテキストには、中間層のトランザクションサービス、データアクセスオブジェクト、またはアプリケーション全体で使用(および再利用)する可能性のある他のオブジェクトなどのコンポーネントが含まれる場合があります。アプリケーションごとに1つのアプリケーションコンテキストがあります。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/generalApplicationContext.xml
    </param-value>
</context-param>

もう1つのコンテキストはWebApplicationContextで、これはアプリケーションコンテキストの子コンテキストです。 Spring Webアプリケーションで定義された各DispatcherServletには、関連付けられたWebApplicationContextがあります。 WebApplicationContextの初期化は次のように行われます。

<servlet>
    <servlet-name>my-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

詳細については、 this および this を参照してください。

8
Ankur Singhal

実際にSpringのデバッグログを取得するより良い方法は、自分自身に順序を伝えます。コードにアクセスしたい場合は、org.springframework.web.servlet.FrameworkServletDispatcherServletはこのクラスを拡張します)ロガーを有効にするだけ"org.springframework.web.servlet"好みのロギングフレームワークのデバッグレベル

通常、ログは次のようになります。ルートコンテキストが最初にロードされ、コンテキスト階層の親として設定されていることは明らかです。次にサーブレットコンテキストがロードされます。

INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/generalApplicatonContext.xml]
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 256 ms
DEBUG: org.springframework.web.servlet.DispatcherServlet - Initializing servlet 'my-servlet'
INFO :Initializing Spring FrameworkServlet 'appServlet'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'my-servlet': initialization started
DEBUG: org.springframework.web.servlet.DispatcherServlet - Servlet with name 'appServlet' will try to create custom WebApplicationContext context of class 'org.springframework.web.context.support.XmlWebApplicationContext', using parent context [Root WebApplicationContext: startup date [Fri May 15 17:08:24 IST 2015]; root of context hierarchy
DEBUG: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/specificApplicationContext.xml
7
Shailendra

Web.xmlスプリングでContextLoaderListenerを使用している場合、最初にgeneralApplicationContext.xmlがロードされます。これにより、Beanが作成され、すべてのサーブレットとフィルターが提供されます。このxmlには、アプリケーションで使用される共通クラスであるBeanが必要です。

サーブレットコンフィグレーションで起動時にロードするため、後のスプリングコンテナはspecificApplicationContext.xmlをロードします。起動時のロードを指定しない場合、このspecificApplicationContext.xmlは、特定のurl-patternを使用してアプリケーションに最初のリクエストが届くとロードされます。

ある設定から別の設定にspringconfigを移動するときの質問として、これはアプリケーションリソースの可用性をコンテナに変更します。 generalApplicationContext.xmlでController Beanを指定し、specificApplicationContext.xmlでそれらを指定しない場合、DispatcherServletはマッピングを見つけられないため、404エラーが表示されます。

いくつかのBeanオブジェクトをオンデマンドで作成する場合は、もう1つのservlet-configを作成して、その特定の特定のConfigurationFile2.xmlをロードし、url-patternにマップできます。

3