TransWikia.com

Spring Boot Beanのスコープであるsingletonとapplicationの違いについて

スタック・オーバーフロー Asked by waku123 on September 1, 2021

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

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

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

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

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

よろしくお願いいたします。

2 Answers

こんにちは、はじめまして。

基本的には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上で動作している場合で成立します。
    • 1つのTomcat上で複数のwarをデプロイするとその数だけServletContextが存在することになります。
    • 1つのSpring Bootアプリケーション上で必要に応じてApplicationContextを作成できます(4.1.5. Fluent Builder API)。
  • ApplicationContext は複数のServlet間で共有できます(1.1.1. Context Hierarchy)。

本文の記述内容についても誤認識(あるいは理解不足)があるように思われますので、個人的には、そちらの回答はむしろ理解の妨げになるように感じます。

Answered by DEWA Kazuyuki - 出羽和之 on September 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP