2012-06-21 24 views
37

すべてのコントローラはSpring MVCシングルトンであり、異なるセッションと要求で共有されていますか?Springコントローラのスコープとそのインスタンス変数

もしそうなら、私は

public String name; 

のようなクラス変数は、すべての要求とのセッションのために同じになることを想定しますか? User Xが要求を行い、namePaulに設定されている場合、ユーザーZもPaulとして属性を持っていますか?その後、session.getAttribute()/request.getAttribute()

答えて

53

はあなたの最初の質問に答えるために、セッション/リクエスト変数を持っているために、より簡単に、よりクリーンなOOP-方法があるかどう私の場合は

は私がその行動をしたいが、不思議に思っていない:はいSpring MVCコントローラは、デフォルトではシングルトンです。オブジェクトフィールドは共有され、すべての要求とすべてのセッションで永遠に表示されます。

しかし、どのような同期もなしに、あらゆる並行性の問題(競合状態、可視性)に遭遇する可能性があります。したがって、あなたのフィールドは可視性の問題を避けるためにvolatile(そして、private、ちなみに)修飾子を持つ必要があります。春にはあなたが要求 - を使用することができます(4.5.4.2 Request scopeを参照)、セッションスコープ(参照:4.5.4.3 Session scopeを)豆戻るあなたの主な質問へ

。それらをコントローラや他のBean(たとえシングルトンでも)に注入できますが、Springは各リクエスト/セッションが独立したインスタンスを持つようにします。シングルトンに要求 - とセッションスコープの豆を注入すると、スコーププロキシ(4.5.4.5 Scoped beans as dependenciesから取られた例)でそれらをラップするときに覚えておくべき

だけの事:

<!-- an HTTP Session-scoped bean exposed as a proxy --> 
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"> 

    <!-- instructs the container to proxy the surrounding bean --> 
    <aop:scoped-proxy/> 
</bean> 
+0

+1注:「さらにシングルトン!注入された豆を自動プロキシする必要があります –

+0

@SeanPatrickFloyd:はい、これは非常に重要なので、私はSpringのドキュメントからサンプルを追加しました。 –

8

はい、春MVCのコントローラはシングルトンです。複数のリクエストの間で、クラス変数が共有され、あいまいになることがあります。 コントローラーの上に@Scope( "request")注釈を付けると、あいまいさを避けることができます。

+0

説明のある例は素晴らしいでしょう。 – Nilambar

+0

@Controller パブリッククラスTestClass { \tプライベートString name; \t @RequestMapping( "/") \tパブリック文字列のdisplayName(){ \t \t IF(this.name = NULL!){ \t \t \t this.name = "ABC"。 \t \t}他{ \t \t \t this.name = "XYZ"。 \t \t} SystemOut.println(name); \t \tこれを返す。名; \t} \t public String getName(){ \t \t return name; \t} \t {\t \t this.name = name; } } –

+0

最初のリクエストではXYZが印刷されますが、もう1つの並列リクエストではABCが印刷されますが、2人のユーザーが2つの異なるリクエストを発行している場合はXYZが表示されるのが理想です。 @Scope( "request")を作成することで、望ましい結果が得られます。私がどこかで間違っていたらどうか私に知らせてください。 –