質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.99%

Springアプリケーションのインスタンスのスコープについて

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,880

lupus_dingo

score 277

SpringでWebサービスを作成しています。
「シングルトン」というキーワードについて調べていたところ、
「インスタンスの生成はコストが高いのでgetInstance()などの
メソッドを作成し、インスタンスが生成されてない場合のみnewすること」とありましたが
そもそもリクエストを受けて生成したインスタンスのスコープがよくわかってません。

Helloを出力するような単純なコンソールプログラムなら
javaコマンドでプログラムを起動し、該当箇所(new Hello()など)でインスタンスを生成して
プログラム終了時にすべて破棄されるというイメージはつきます。
Webサービスの場合はリクエストを受けてからアクションやサービスクラスの該当箇所(new Hello()など)で
インスタンスを生成し、レスポンスを返すときに破棄されると思っていたのですが、
シングルトンを調べているとインスタンスを使いまわすというような記述があります。
ということは、クライアント(A)からリクエストがあり任意のインスタンス生成する処理があった場合、
生成されたインスタンスは他のクライアント(B)も参照・変更可能になっているということでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • A-pZ

    2016/03/24 17:54

    タイトルと本文が異なります。サーブレットではなくSpringアプリケーションのスコープの質問ではないでしょうか。

    キャンセル

  • lupus_dingo

    2016/03/24 19:34

    指摘ありがとうございます。修正しました。

    キャンセル

回答 3

+1

シングルトンのインスタンスの、スコープは、tomcat 起動から、tomcat 終了まで。
クライアント(A)、クライアント(B) ともに 同じインスタンスに アクセスします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/24 19:08 編集

    回答ありがとうございます。
    tomcatが起動している間ということはサーバ再起動しない限り
    同じインスタンスということですね。

    同じインスタンスにアクセスしているのを確認したいのですが
    どうやったら簡単に確認するできるでしょうか?
    IDEはEclipseとほぼ同じSTSを使っています。

    キャンセル

  • 2016/03/24 20:21

    tkturbo さんの方法で確認できました。
    ありがとうございました。

    キャンセル

checkベストアンサー

0

サーブレット、リクエスト、セッションなどの変数スコープについてはそれぞれのライフサイクル内で生成・終了されます。(詳しくは→サーブレットのライフサイクルとインスタンス変数 - サーブレットの基本 - サーブレット入門
よくあるシングルトンパターンでは「最初に参照されたとき」にインスタンスが生成され、以降使いまわされます。
使いまわされるのが同一プロセス内なのでtomcatのプロセスが生きてる間中ずっと残り続けるのです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/24 19:14

    回答ありがとうございます。

    URL参考にさせてもらいます。
    また、同じインスタンスにアクセスしているのを確認したいのですが
    簡単に確認するできる方法があったら教えてほしいです。
    IDEはEclipseとほぼ同じSTSを使っています。

    キャンセル

  • 2016/03/24 19:32 編集

    1.外部からgetter/setterでアクセス可能なフィールドを持つシングルトンインスタンスを用意する。
    2.サーブレットを二つ用意する。
    3.どちらのサーブレットも内部でシングルトンなインスタンスにアクセスできるようにしておく
    4.サーブレット1にアクセスしたらシングルトンインスタンスに値をsetする。
    5.サーブレット2にアクセスしたらシングルトンインスタンスから値をgetして表示する。
    → 4でセットされた値が5で表示されたらいいんじゃないすか?

    キャンセル

  • 2016/03/24 20:12 編集

    回答ありがとうございます。
    アドバイスを基に以下のようなクラスを作って別クラスからgetter/setterを呼んでみました。すると確かに複数回処理を呼ぶと数値がインクリメントされたので同じインスタンスを使いまわしていることが確認できました。
    私はIDE上でデバッグする際、レスポンスが返るとデバッグも終了するのでそこですべてリセットされると思っていました。デバッグは終わってもいったん生成されたオブジェクトはすべて残ったままになるのですね。勉強になりました。
    ********
    ```java
    public class SingletonCheck {

    private static SingletonCheck instance = new SingletonCheck();
    private int num;

    private SingletonCheck() {}

    public static SingletonCheck getInstance() {
    return instance;
    }

    public int getNum() {
    return this.num;
    }
    public void setNum(int i) {
    this.num = this.num + i ;
    }

    }
    ```

    キャンセル

0

Spring frameworkで扱われる代表的なスコープの2つである シングルトン(Singleton)とプロトタイプ(Prototype)の違いについてですが、シングルトンはアプリケーションで1つのインスタンスを共有する、プロトタイプはSpringからインスタンスを取得するたびに新しく作る、の違いがあります。

なお他にもHTTPリクエスト単位でインスタンスを作るリクエスト(Request)やサーブレットのセッション単位(Session)もありますので、アプリケーションの設計にあわせてお使いください。

参考サイト:
http://javatechnology.net/spring/spring-singleton-scope/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/24 19:32

    回答ありがとうございます。
    Controllerってシングルトンだったんですね。

    参考サイトを見てみましたがアノテーションに対する理解が乏しいので
    事前知識を用意してからでないとまだ理解できなそうです。
    ただ、@Scope("prototype")を入れるとシングルトンじゃなくなることはわかりました。
    JdbcTemplateとか決まりきった設定オブジェクトを共有するのはなんとなくわかります。
    でもControllerやServiceがシングルトンということは、1ユーザの処理をしている間に他のユーザが同じインスタンスを操作する可能性があるということですが、これは極力@Scope("prototype")をつけないと処理がバッティングするのでやばいということでしょうか?

    キャンセル

  • 2016/03/30 21:44

    Springでシングルトンにした場合に気を付けなければならないのが、クラスのフィールド(メンバ変数)が複数の呼び出し元から共有されてしまうことでしょうか。
    ただしすべてにprototypeをつけると、呼び出されるごとにインスタンスを作りますのでそれだけメモリを消費しますし、生成の時間も多少かかります。(自動的にガベージコレクトの対象にはなるかと思いますが、破棄する処理もそれなりに時間がかかります)

    一般的な作り方では、Controller層はprototypeないしはrequestにし、そこから呼び出されるクラス(Serviceなど)はsingletonであれば、たいていは問題ないかと思いますし、メンバ変数の利用も問題ないでしょう。

    キャンセル

  • 2016/03/31 20:24

    回答ありがとうございます。
    とても参考になります。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる