スタック・オーバーフロー Asked by waku123 on September 1, 2021
SpringBootのBeanのスコープで分からない事があります。
ご存知の方がおられましたら、ご教授いただけますでしょうか。
【質問】
Beanのスコープにsingletonとapplicationがあります。
このスコープの違いが分からないのですが、何が違うのでしょうか。
singleton、applicationは以下の様に記述されていましたが、
同じような事(Webアプリケーション毎に共有する事が可能?)を言っているように
見受けられるのですが、違うのでしょうか、
【singleton】
DIコンテナの起動時に、Beanのインスタンスを生成し、同一のインスタンスを共有して利用する。
【application】
サーブレットのコンテキスト単位でBeanのインスタンスを生成する。
よろしくお願いいたします。
こんにちは、はじめまして。
基本的にはSpringアプリケーション内で参照できるコンポーネントであることに違いはありません。
Singletonスコープ、の場合は同一の ApplicationCotext 内から参照できます。
Applicationをスコープにした場合は、ServeltContext の単位で参照できるコンポーネントになります。
ServletContextは複数のApplicationContextを保持している場合があります。
簡単にいえば同じシステムの中で複数のアプリケーションが動いている場合横断して参照できるスコープです。
基本的にはデフォルトで、Singletonになることから分かるように実装上の理由がなければ、Singletonを利用すればよいと思います。
ApplicationContextはSpring固有のもので、ServletContextはJavaサーブレットの一般的な概念にあたるので、混乱しないように注意しましょう。
参照URL :
https://stackoverflow.com/questions/49819633/spring-singleton-scope-vs-application-scope/49820934
https://www.baeldung.com/spring-bean-scopes
Spring Boot(MVC)は下記のようにDipsatcherServletを経由して動作します。なのでこの一個のDispatcherServeltの範囲が、applicationContextで、Singletonスコープが参照できる範囲です。applicationレベルのスコープでは複数のDispatcherServletを参照できます。
粒度のレベルがJavaServletの概念と違うので、片方しか使わないなら混同するのでJavaServletの仕組みは忘れてしまう/参考にしないのもいいんじゃないかと思います。
https://yiingw.files.wordpress.com/2017/07/springmvc1.jpg?w=640
Correct answer by Kouki.W on September 1, 2021
簡単に:
Spring Bootをウェブアプリケーションフレームワークとして利用する場合、Java EE Servlet specに則った Servlet Container(例えばTomcat)上で動作させます。
application-scope は Servlet containerであるところのTomcatが管理するメモリ空間(ServletContext
)にbeanを置きます。
singleton-scope は IoC container であるところのSpring自身が管理するメモリ空間(ApplicationContext
)にbeanを置きます。
なので、 application-scope ⊇ singleton-scope という関係になりますが、典型的なSpring Bootアプリケーションでは ApplicationContext
は1つだけで十分であり、いわゆるsingletonとしたいオブジェクトはwebスタックに依存しないApplicationContext
で管理するのが一般的かと思います。
もう少し正確に:
質問文に記載されている各scopeに関する説明文のオリジナルは、Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発という書籍の2.1.7 Beanのスコープ 節にある 「表2.4 Spring Framework で利用可能なスコープ」 です。
(web上でヒットするのはこの書籍からの引き写しと思われます)
そして、この表は 公式リファレンス 1.5. Bean Scopes 節 にある「Table 3. Bean Scopes」を翻訳したものです。
この部分の後続の 「Application Scope」節で、質問文の疑問に対して直接言及されています:
This(注: application-scope beanのこと) is somewhat similar to a Spring singleton bean but differs in two important ways: It is a singleton per ServletContext, not per Spring 'ApplicationContext' (for which there may be several in any given web application), [後略]
ここで、 "application" や "singleton" という用語は、それぞれのcontext上で認識される単位の application や singleton であり、同じ単語でも指しているものが違うことに注意してください。
例えば、ApplicationContext
の "application" はIoC Container上のアプリケーションという単位を指していますが、scope名の application
は Servlet Container上のアプリケーション(いわゆるwebアプリケーション)を指している、という具合です。
補足:
ServeltContextとは以下のURLの画像1にあるサーブレットコンテナと同じ範囲のイメージでしょうか。また、ApplicationCotextとは各Webアプリケーション毎と同じ範囲のイメージでしょうか。(link)
についてですが、前述の通り、サーブレットコンテナというのはTomcatのこと、コンテキストというのが ServletContext
のことです(contextというのは1つのアプリケーションが動作する境界付けられたメモリ空間、みたいな認識で取り敢えずは良いかと思います)。
「各Webアプリケーション毎」は、正確には ServletContext
(図中の「コンテキスト」が該当)ですが、これも前述の通り、一般的なSpring Bootアプリケーションでは大抵の場合ApplicationContext
も同等、と見なせるでしょう。
また、こちらのコメント
含まれる各サーブレットがアプリケーション全体と通信するためのインターフェースをサーブレットコンテキストと呼びます。コンテキスト(文脈)はJVMにつき一個です、この図は少し分かりづらいですね。モジュール単位で下記のリンク先のの図にあるサーブレットがApplicationContextの範囲になります。(link)
について、最初のコンテキストの説明が私には理解できませんでしたが、少なくとも「コンテキストがJVMにつき1つ」「リンク先のServletがApplicationContext
の範囲」というのは誤りです。
ServletContext
にしろ ApplicationContext
にしろ今回登場しているものは全て同一JVM上で動作している場合で成立します。
ServletContext
が存在することになります。ApplicationContext
を作成できます(4.1.5. Fluent Builder API)。ApplicationContext
は複数のServlet間で共有できます(1.1.1. Context Hierarchy)。本文の記述内容についても誤認識(あるいは理解不足)があるように思われますので、個人的には、そちらの回答はむしろ理解の妨げになるように感じます。
Answered by DEWA Kazuyuki - 出羽和之 on September 1, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP