8

私はしばらくの間徐々にSpringを理解してきており、概念については合理的な考えを持っていると思いますが、別のスレッドで情報に出くわし、状況が逆転しました...

「...初期化ライフサイクルコールバックメソッドはスコープに関係なくすべてのオブジェクトで呼び出されますが、プロトタイプの場合、構成された破棄ライフサイクルコールバックは呼び出されません。クライアントコードは、プロトタイプスコープのオブジェクトをクリーンアップし、プロトタイプBeanの高価なリソースを解放する必要があります保持しています。SpringコンテナでプロトタイプスコープのBeanが保持するリソースを解放するには、クリーンアップが必要なBeanへの参照を保持するカスタムBeanポストプロセッサを使用してみてください。」

これにより、たとえば、リクエストごとに「新しい」Beanインスタンスが必要な場合など、プロトタイプBeanを使用したいという実際のユースケースがあると思いました。ただし、このスニペット(Spring 3のドキュメントから)について私が理解していることから、Springはクリーンアップが必要なBeanへの参照を保持しています(参照自体は、Beanがガベージコレクターによって自動的にクリアされないことを意味します)。さらに、このことから、プロトタイプBeanが保持しているリソースを手動でクリーンアップする必要があると考えています。

これが正しいかどうか誰かに知らせてもらえますか?もしそうなら、これに対処するために使用される典型的なパターンはありますか?SpringがこのようにプロトタイプBeanを実装するアーキテクチャ上の理由を説明できる回答をいただければ幸いです。

4

3 に答える 3

19

Spring は、クリーンアップが必要な Bean への参照を保持します (参照自体は、Bean がガベージ コレクターによって自動的にクリアされないことを意味します)。

はい。ただし、コンテナーはプロトタイプ スコープの Bean への参照を保持しません。これが、破棄コールバックが呼び出されない理由です。Spring は Bean インスタンスを作成し、それをワイヤリングして、構築コールバックを呼び出します。インスタンスを提供し、その Bean を忘れます。

リクエストごとにプロトタイプ スコープの Bean を安全に作成できます。Spring はインスタンスを提供し、その Bean への参照がなくなると (Spring は 1 つも保持しません!)、ガベージ コレクションが実行されます。しかし、Spring は Bean を作成した後は何も知らないので、破壊コールバックを呼び出すことはできません。実際、これは質問に要約されます。なぜ Java にはデストラクタがないのですか。

では、プロトタイプ スコープの Bean をどのようにクリーンアップしますか? Java の他のリソースを明示的にクリーンアップするのと同じように。close()destroy()、または任意stop()の名前を指定します ( の実装を検討してCloseableください。通常、このようなメソッドは必要ないことに注意してください。ガベージ コレクターはオブジェクト グラフ全体を解放しますが、データベース接続などの永続的なリソースは、全体DataSourceが閉じられると閉じられます。

于 2012-06-08T21:42:26.890 に答える
8

ドキュメントを読み間違えました。明示的に次のように述べています。

Spring コンテナーがプロトタイプ スコープの Bean によって保持されているリソースを解放するようにするには、クリーンアップする必要がある Bean への参照を保持するカスタム Bean ポスト プロセッサを使用してみてください。

したがって、Spring は、作成するプロトタイプ Bean への参照を保持しません。必要に応じて、これらの Bean への参照を保持する Bean ポスト プロセッサを作成するのはあなた次第です。

さらに、プロトタイプ Bean がクリーンアップが必要なリソースを保持することはほとんどありません。たとえば、接続プール (シャットダウン時に適切に破棄する必要がある) は通常、シングルトン Bean です。それをプロトタイプにする意味はあまりありません。プロトタイプ Bean は短時間しか使用されないことが多いため、プロトタイプ Bean を作成するクライアントは、使用しなくなったときにそのリソースを明示的に解放できます。新しいストリームまたは接続を作成し、finally ブロックで閉じる場合と同様です。

于 2012-06-08T21:43:55.100 に答える
6

Spring は、プロトタイプ スコープを使用して作成されたすべてのインスタンスに関する知識はありません。ドキュメントにコメントされているように、プロトタイプ スコープ Bean をインスタンス化して構成し、それをクライアントに渡すだけです。

Spring は、プロトタイプ Bean の完全なライフサイクルを管理しません。コンテナーは、プロトタイプ オブジェクトをインスタンス化し、構成し、装飾し、その他の方法でアセンブルし、それをクライアントに渡します。その後、そのプロトタイプ インスタンスについてそれ以上の知識はありません。

http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s04.html#beans-factory-scopes-prototype

于 2012-06-08T21:46:24.430 に答える