典型的なSpring MVCプロジェクトには2つの「コンテナ」があります。1つはContextLoaderListenerによって作成され、もう1つはDispatchServletによって作成されます。
知りたいのですが、これらは本当に2つのIoCコンテナインスタンスですか?(2つのBean設定ファイルがあり、1つはroot-context.xml
もう一方はservlet-context.xml
)
コンテナが2つある場合、関係はどうなりますか?
あるコンテナで宣言されたBeanを別のコンテナで使用できますか?
春の公式ウェブサイト から:
インターフェース
org.springframework.context.ApplicationContext
はSpring IoCコンテナーを表し、前述のBeanのインスタンス化、構成、およびアセンブルを担当します。コンテナは、構成メタデータを読み取ることにより、どのオブジェクトをインスタンス化、構成、およびアセンブルするかに関する指示を取得します。構成メタデータは、XML、Java注釈、またはJavaコードで表されます。
再び公式ドキュメントから:
Web MVCフレームワークでは、各DispatcherServletには独自のWebApplicationContextがあり、ルートWebApplicationContextですでに定義されているすべてのBeanを継承します。これらの継承されたBeanは、サーブレット固有のスコープでオーバーライドできます。また、特定のサーブレットインスタンスに対してローカルな新しいスコープ固有のBeanを定義できます。
述べられているように、今あなたの質問に来ます ここ :
Spring Webアプリケーションには、2種類のコンテナがあり、それぞれが異なる方法で構成および初期化されます。 1つは「アプリケーションコンテキスト」で、もう1つは「Webアプリケーションコンテキスト」です。最初に「アプリケーションコンテキスト」について説明しましょう。アプリケーションコンテキストは、web.xmlで定義されたContextLoaderListenerまたはContextLoaderServletによって初期化されたコンテナであり、構成は次のようになります。
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:*-context.xml</param-value> </context-param>
上記の構成では、*-context.xmlに一致するクラスパスからすべてのファイルをロードし、そこからアプリケーションコンテキストを作成するよう、springに要求しています。たとえば、このコンテキストには、中間層のトランザクションサービス、データアクセスオブジェクト、またはアプリケーション全体で使用(および再利用)する可能性のある他のオブジェクトなどのコンポーネントが含まれる場合があります。アプリケーションごとに1つのアプリケーションコンテキストがあります。
もう1つのコンテキストは、アプリケーションコンテキストの子コンテキストである「WebApplicationContext」です。 Spring Webアプリケーションで定義された各DispatcherServletには、関連付けられたWebApplicationContextがあります。 WebApplicationContextの初期化は次のように行われます。
<servlet> <servlet-name>platform-services</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:platform-services-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Spring構成ファイルの名前をサーブレット初期化パラメーターとして指定します。ここで覚えておくべき重要なことは、XMLの名前は-servletという形式でなければならないということです。 xml。この例では、サーブレットの名前はplatform-servicesであるため、XMLの名前はplatform-service-servlet.xmlでなければなりません。 ApplicationContextで利用可能なBeanはすべて、各WebApplicationContextから参照できます。ビジネスロジックコンポーネントやデータアクセスクラス(通常ApplicationContextで定義される)などの中間層サービスと、コントローラーやビューリゾルバーなどのWeb関連コンポーネントを明確に分離することがベストプラクティスです。 Dispatcher ServletごとのWebApplicationContext)。
これらのリンクを確認してください
Spring FrameworkのapplicationContext.xmlとspring-servlet.xmlの違い
2つの個別のコンテナは作成されません。通常、オブジェクトが必要な場合、servlet-context.xmlで宣言されたオブジェクトをspringでインスタンス化します。したがって、servlet-context.xml構成ファイルをDispatcher Servletにマップします。つまり、リクエストがディスパッチャーサーブレットにヒットしたときにオブジェクトを初期化します。
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
コンテキストがロードされているときにオブジェクトを初期化してアクションを実行する場合、デプロイメント記述子のcontext-param
タグで構成ファイルを宣言します。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
Servlet-context.xmlとroot-context.xmlで別々のBeanを宣言し、それらをカスタムContext Loader Listenerクラスで自動配線することにより、これをテストできます。ルートコンテキストインスタンスのみが初期化され、サーブレットコンテキストBeanがnullであることがわかります。
Spring MVCには少なくとも2つのコンテナがあります-
によって宣言されたアプリケーションコンテキスト
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
-によって宣言されたサーブレットコンテキスト
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
また、Webアプリケーションは、任意の数のDispatcherServlet
を定義できます。各サーブレットは独自の名前空間で動作し、マッピングやハンドラーなどを使用して独自のアプリケーションコンテキストをロードします。ContextLoaderListener
によってロードされたルートアプリケーションコンテキストのみが共有されます。したがって、子コンテナはいくつでも持つことができます。