4

私は、Unity、Ninject、Castle Windsor などの依存性注入コンテナーを使用する .NET のバックグラウンドを持っています。最近、Spring の依存性注入機能を Java に使用する方法を学び始めました。

Spring の学習において、bean XML 構成で「init-method」および「destroy-method」の概念を指定できることを確認しました。

「init-method」を指定する目的は、Bean の作成時に必要なセットアップを行うことのようです。ここで私は混乱します。通常/適切なオブジェクト指向設計が指示するように、コンストラクターを使用してオブジェクトに必要なセットアップを実行するのではなく、セットアップを実行するための別のメソッドが必要なのはなぜですか?

言い換えれば、クラスで依存関係が必要な場合、呼び出されたことがわかっているコンストラクターに注入するべきではありませんが、オブジェクトは「init-method」を呼び出さずに状態で存在できますか?

4

3 に答える 3

9

init()別の方法が必要な場合はほとんどありません。

  • 選択の余地がないレガシーAPI

  • 初期化にはいくつかの副作用があります。たとえば、開始、Thread外部リソースへの接続などです。

    これは実際にはさらに深い意味を持っています:クラスベースのプロキシを使用する場合(を介して)、基本クラスのコンストラクターが2回呼び出されます(クラスから継承するプロキシの場合は2回目)-init()メソッドは最終オブジェクトで1回だけ呼び出されます。

  • コンストラクターで仮想呼び出しを実行しないでください(これは実際にはコンパイラーによって禁止されているはずです...)

  • セッター/フィールドインジェクションを使用する必要がある場合があります(コンストラクターインジェクションは大好きですが)。たとえば、前述のクラスベースのプロキシを使用する場合などです。

通常の/優れたオブジェクト指向設計が指示するように、コンストラクターを使用してオブジェクトに必要なセットアップを実行しますか?

これは、すべての初期化コードをコンストラクターに配置するための実際のベストプラクティスではありません。コンストラクターの副作用により、テストとモックがはるかに困難になります。代わりに、安定した既知の状態のオブジェクトの作成に焦点を合わせます。このようにして、たとえば、接続プールを管理するオブジェクトの作成とそのプールへの物理的な接続を切り離すことができます。

ところでdestroy()、外部リソースを感謝して閉じたり、スレッドを中断したりできるので、デストラクタのない言語の祝福です。頻繁に使用してください。

于 2012-07-08T08:42:10.627 に答える
5

なぜそれが必要なのですか?

init メソッドは、Bean のすべてのプロパティが設定された後に呼び出されます。これは通常、すべてのプロパティが設定された後にのみ実行できるプロパティの初期化または検証を Bean が実行する必要がある場合に必要です。(「init」コールバックを使用せずにこれを実行しようとすると、各プロパティ セッターが他のセッターが呼び出されたかどうかなどを確認する必要があることがわかります。すべてのプロパティの後でしか初期化を実行できない場合、その戦略でさえ失敗します。 Bean のサイクルで設定されています。)

Bean が明示的に解放する必要があるリソースを保持している場合は、destroy メソッドが必要です。たとえば、ファイル ハンドル、ネットワーク ソケット、データベース接続などです。

...通常の/優れたオブジェクト指向設計が指示するように?

init および destroy イベント/メソッドが「間違っている」または「禁止されている」と指示する設計方法論は非現実的であり、無視する必要があります。実際、オブジェクト指向の設計方法論では通常、これは指示されていません。せいぜい、この種のことは通常は必要ないと言うでしょう。

さらに、DI は実際には設計方法論のルールをいくらか変更します...少なくとも初期化に関しては。特に、インスタンスの「配線」を外部化することで、従来の OO 設計方法論では予期しない方法で、コードからロジックを大幅に引き出すことができます。どちらかといえば、これは、依存性注入に照らして、従来の OO 方法論を再検討する必要があることを示しています。

于 2012-07-08T04:16:04.870 に答える
0

セッター注入を使用している場合は、すべてのプロパティが設定/自動配線された後に初期化を行うために、init メソッド/InitializingBean/@PostConstruct が確実に必要です。それ以外の場合は、構築されているが依存関係が注入されていないオブジェクトがあります。コンストラクター注入を使用している場合、Tomasz と Stephen によって指摘されたケースでは、ほとんど必要ありません。

于 2012-07-09T02:50:45.510 に答える