68776
SpringBootのBeanのスコープで分からない事があります。  
ご存知の方がおられましたら、ご教授いただけますでしょうか。

【質問】  
Beanのスコープにsingletonとapplicationがあります。  
このスコープの違いが分からないのですが、何が違うのでしょうか。

singleton、applicationは以下の様に記述されていましたが、  
同じような事(Webアプリケーション毎に共有する事が可能？）を言っているように  
見受けられるのですが、違うのでしょうか、

【singleton】  
DIコンテナの起動時に、Beanのインスタンスを生成し、同一のインスタンスを共有して利用する。

【application】  
サーブレットのコンテキスト単位でBeanのインスタンスを生成する。

よろしくお願いいたします。
CC BY-SA 4.0
2020-07-21T01:20:23.680
68772
2020-07-25T16:22:59.453
37340
question
spring-boot
Spring Boot Beanのスコープであるsingletonとapplicationの違いについて
こんにちは、はじめまして。

基本的には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>
CC BY-SA 4.0
2020-07-21T03:17:38.053
68776
2020-07-21T14:18:35.150
2020-07-21T14:18:35.150
37777
37777
68772
answer
簡単に:

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`で管理するのが一般的かと思います。

  * [Spring MVC - 1.1.1. Context Hierarchy](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/web.html#mvc-servlet-context-hierarchy)

* * *

もう少し正確に:

質問文に記載されている各scopeに関する説明文のオリジナルは、[Spring徹底入門 Spring
FrameworkによるJavaアプリケーション開発](https://www.shoeisha.co.jp/book/detail/9784798142470)という書籍の2.1.7
Beanのスコープ 節にある 「表2.4 Spring Framework で利用可能なスコープ」 です。  
(web上でヒットするのはこの書籍からの引き写しと思われます)

そして、この表は 公式リファレンス [1.5. Bean Scopes
節](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-
reference/core.html#beans-factory-scopes) にある「Table 3. Bean Scopes」を翻訳したものです。

この部分の後続の 「[Application
Scope](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-
reference/core.html#beans-factory-scopes-application)」節で、質問文の疑問に対して直接言及されています:

> 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アプリケーション)を指している、という具合です。

* * *

補足:

[こちらのコメント](https://ja.stackoverflow.com/questions/68772/spring-boot-
bean%e3%81%ae%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%97%e3%81%a7%e3%81%82%e3%82%8bsingleton%e3%81%a8application%e3%81%ae%e9%81%95%e3%81%84%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6#comment75630_68776)

>
> ServeltContextとは以下のURLの画像１にあるサーブレットコンテナと同じ範囲のイメージでしょうか。また、ApplicationCotextとは各Webアプリケーション毎と同じ範囲のイメージでしょうか。([link](https://www.itmedia.co.jp/enterprise/0212/09/epn14.html))

についてですが、前述の通り、サーブレットコンテナというのはTomcatのこと、コンテキストというのが `ServletContext`
のことです(contextというのは1つのアプリケーションが動作する境界付けられたメモリ空間、みたいな認識で取り敢えずは良いかと思います)。

「各Webアプリケーション毎」は、正確には `ServletContext`(図中の「コンテキスト」が該当)ですが、これも前述の通り、一般的なSpring
Bootアプリケーションでは大抵の場合`ApplicationContext`も同等、と見なせるでしょう。

また、[こちらのコメント](https://ja.stackoverflow.com/questions/68772/spring-boot-
bean%e3%81%ae%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%97%e3%81%a7%e3%81%82%e3%82%8bsingleton%e3%81%a8application%e3%81%ae%e9%81%95%e3%81%84%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6#comment75632_68776)

>
> 含まれる各サーブレットがアプリケーション全体と通信するためのインターフェースをサーブレットコンテキストと呼びます。コンテキスト(文脈)はJVMにつき一個です、この図は少し分かりづらいですね。モジュール単位で下記のリンク先のの図にあるサーブレットがApplicationContextの範囲になります。([link](https://examples.javacodegeeks.com/wp-
> content/uploads/2017/12/servlet-configcontext-archi-guide-2.jpg.webp))

について、最初のコンテキストの説明が私には理解できませんでしたが、少なくとも「コンテキストがJVMにつき1つ」「リンク先のServletが`ApplicationContext`の範囲」というのは誤りです。

  * `ServletContext` にしろ `ApplicationContext` にしろ今回登場しているものは全て同一JVM上で動作している場合で成立します。 
    * 1つのTomcat上で複数のwarをデプロイするとその数だけ`ServletContext`が存在することになります。
    * 1つのSpring Bootアプリケーション上で必要に応じて`ApplicationContext`を作成できます([4.1.5. Fluent Builder API](https://docs.spring.io/spring-boot/docs/2.3.2.RELEASE/reference/htmlsingle/#boot-features-fluent-builder-api))。
  * `ApplicationContext` は複数のServlet間で共有できます([1.1.1. Context Hierarchy](https://docs.spring.io/spring/docs/5.2.7.RELEASE/spring-framework-reference/web.html#mvc-servlet-context-hierarchy))。

[本文](https://ja.stackoverflow.com/a/68776/2808)の記述内容についても誤認識(あるいは理解不足)があるように思われますので、個人的には、そちらの回答はむしろ理解の妨げになるように感じます。
CC BY-SA 4.0
2020-07-25T00:34:39.087
68925
2020-07-25T16:22:59.453
2020-07-25T16:22:59.453
2808
2808
68772
answer