0

私は Spring.NET を使用して Command オブジェクトを作成し (アドバイスが添付されています)、MVC Web アプリケーションでこれらを実行しています。

しかし、私は私が戻ってきたオブジェクトを観察しました

IApplicationContext ctx = ContextRegistry.GetContext();
MyObject obj = (MyObject) ctx.GetObject ("MyObject");

以前のリクエストからの値を「記憶」していたため、予想どおり、新しいオブジェクトではありませんでした。

さらに悪いことに、この共有インスタンスが APPLICATION 全体にあるのではないかと疑っています。Web 要求のマルチスレッドの性質により、コマンドが実行されてデータベースに書き込まれると、詳細がごちゃまぜに書き込まれる可能性があります。複数のリクエストから。

私の恐れは根拠がありますか?共有オブジェクトではなく、常に新鮮でクリーンな新しいオブジェクトに戻すスイッチはありますか? Web アプリで Spring IOC を引き続き使用できるはずだと感じています。

4

2 に答える 2

3

Spring.NET Webアプリケーションは、オブジェクトのスコープを制御できるようにするオブジェクト定義要素内の追加の属性をサポートしています。

<object id="myObject" type="MyType, MyAssembly" scope="application | session | request"/>

リクエスト、セッション、およびアプリケーションスコープは、WebApplicationContextなどのWeb対応のSpringIApplicationContext実装を使用する場合にのみ使用できます。

http://www.springframework.net/doc-latest/reference/html/web.html#web-objectscope

于 2012-08-23T07:21:43.817 に答える
0

私自身の質問に答えて、うまくいけば、他の人がこれを役に立つと思うでしょう。

新しい MVC サイトで Spring.NET を使用すると、いくつかの奇妙な動作に気付きました。私は主に Spring の AOP 機能を使用していましたが、そのために IOC を使用してコマンド オブジェクトを作成しました。フローは次のとおりです。

コントローラー -> 'create' コマンド オブジェクト:

var ctx = ContextRegistry.GetContext(); var updateContactCommand = (IUpdateCustomerCommand) ctx["UpdateCustomerCommand"]; コントローラ -> 新しい値でコマンド オブジェクトを設定する

コントローラ -> コマンド オブジェクトを実行し、コマンドの詳細を含む監査行をデータベースに作成する監査アドバイスを実行します。

素晴らしいもの。とか、そう思いました。

特定の条件で特定のフィールドのみを設定するコードがあります。しかし、これを実行すると、条件が満たされていない場合でも、トランザクション全体で、データベースが入力された最後の値を常に保存していることがわかりました。コマンドは、前のトランザクションで設定された値を記憶していました!

もちろん、値を覚えていたわけではありません。単純に、Spring が updateContactCommand を「作成」したときに、以前に作成されたもの、つまりシングルトンを取得しただけでした。

これは、マルチスレッド Web アプリケーションに大きな影響を与えます。同じコマンド オブジェクトを使用して別の要求を行うと、まったく望ましくない動作が発生する可能性があります。

Spring.NET のデフォルトの動作はシングルトンを作成することなので、以下のようにオブジェクト宣言の最後に 'singleton="false"' を追加する必要があります。ただし、AOP を使用していたため、オブジェクト タイプは ProxyFactoryObjects として宣言されており、この時点ではシングルトンは有効ではありません。

答えはまだ構成にあり、次を使用することです。

  <object id="UpdateCustomerCommand" type="DataLib.Commands.UpdateCustomerCommand, DataLib" singleton="false"/>
  <object type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
    <property name="ObjectNames">
      <list>
        <value>UpdateCustomerCommand</value>
      </list>
    </property>
    <property name="InterceptorNames">
      <list>
        <value>beforeAdvice</value>
      </list>
    </property>
  </object>

AutoProxy.ObjectNameAutoProxyCreator の使用に注意してください。

これにより、毎回新しいインスタンスが得られ、おそらくマルチスレッドの問題にも対処できます – まだテスト中です!

ソース: http://forum.springframework.net/showthread.php?7027-Lifecycle-of-objects-how-to-get-a-new-instance-for-each-call-of-GetObject ()

于 2012-08-22T14:18:30.120 に答える