35

注釈が人気になっています。Spring-3はそれらをサポートします。CDIはそれらに大きく依存しています(注釈なしでCDIを使用することはできませんよね?)

私の質問はなぜですか?

私はいくつかの問題を聞いた:

  1. 「XMLを取り除くのに役立ちます」。しかし、xmlの何が悪いのでしょうか?依存関係は本質的に宣言型であり、XMLは宣言型には非常に適しています(命令型プログラミングには非常に適していません)。優れたIDE(アイデアのような)を使用すると、xmlの編集と検証が非常に簡単になりますね。

  2. 「多くの場合、インターフェースごとに1つの実装しかありません」。それは真実ではありません!私のシステムのほとんどすべてのインターフェースには、テスト用のモック実装があります。

他に何か問題はありますか?

そして今、XMLの私の利点:

  1. どこにでも何でも注入できます(注釈のあるコードだけでなく)

  2. 1つのインターフェイスの実装が複数ある場合はどうすればよいですか?修飾子を使用しますか?しかし、それは私のクラスにそれが必要とする注射の種類を知ることを強制します。デザインには良くありません。

XMLベースのDIにより、コードが明確になります。各クラスはインジェクションについて認識していないため、任意の方法で構成して単体テストを行うことができます。

どう思いますか?

4

10 に答える 10

25

私は Guice の経験からしか話せませんが、これが私の見解です。要するに、注釈ベースの構成は、アプリケーションを結び付けるために書かなければならない量を大幅に削減し、何に依存するかを変更するのを容易にします... 多くの場合、構成ファイル自体に触れる必要さえありません。これは、比較的まれな特定のケースを処理するのを少し難しくすることを犠牲にして、最も一般的なケースを完全に自明にすることによって実現します。

クラスに「インジェクションについての知識がない」ことについて独断的になりすぎるのは問題だと思います。クラスのコードでは、インジェクション コンテナへの参照があってはなりません。私はそれに完全に同意します。ただし、1 つの点を明確にしておく必要があります。注釈はコードではありません。それ自体では、クラスの動作については何も変わりません...注釈がまったくないかのように、注釈を使用してクラスのインスタンスを作成できます。したがって、DI コンテナーの使用を完全に停止して、そこに注釈を残すことができ、何の問題もありません。

クラス内でのインジェクションに関するメタデータのヒント (つまり、アノテーション) を提供しないことを選択すると、そのクラスが必要とする依存関係に関する貴重な情報源を捨てることになります。その情報を他の場所 (XML など) で繰り返すか、予期しない問題につながる可能性のある自動配線などの信頼できない魔法に頼らざるを得ません。

特定の質問に対処するには:

XMLを取り除くのに役立ちます

XML 構成には多くの欠点があります。

  • それはひどく冗長です。
  • 特別なツールがなければ型安全ではありません。
  • 文字列識別子の使用が義務付けられています。繰り返しますが、特別なツールのサポートなしでは安全ではありません。
  • 言語の機能をまったく利用せず、コード内の単純なメソッドで実行できることを実行するには、あらゆる種類の醜い構造が必要です。

そうは言っても、多くの人が XML を十分に長く使用してきたので、XML は問題ないと確信しており、その考えが変わるとは思っていません。

多くの場合、各インターフェースには 1 つの実装しかありません

多くの場合、アプリケーションの 1 つの構成(プロダクションなど) に対して、各インターフェースの実装は 1 つだけです。要点は、アプリケーションを起動するときに、通常はインターフェイスを 1 つの実装にバインドするだけでよいということです。その後、他の多くのコンポーネントで使用できます。XML 構成では、そのインターフェースを使用するすべてのコンポーネントに、そのインターフェース (または必要に応じて「Bean」) の特定の 1 つのバインディングを使用するように指示する必要があります。アノテーションベースの構成では、バインディングを一度宣言するだけですそれ以外はすべて自動的に処理されます。これは非常に重要であり、記述しなければならない構成の量が劇的に減少します。また、コンポーネントに新しい依存関係を追加するときに、多くの場合、構成について何も変更する必要がないことも意味します!

いくつかのインターフェースのモック実装があることは関係ありません。単体テストでは、通常、モックを作成して自分で渡すだけです...構成とは関係ありません。代わりにモックを使用して特定のインターフェースを備えた統合テスト用の完全なシステムをセットアップしても、何も変わりません。システムの統合テストの実行では、まだ 1 つの実装しか使用していないため、それを構成する必要があるのは 1 回だけです。

XML: どこにでも何でも注入できます

これは Guice で簡単に行うことができ、CDI でもできると思います。したがって、注釈ベースの構成システムを使用してこれを行うことを完全に妨げられているわけではありません。とは言っても、大部分のアプリケーションに注入されたクラスの大部分は、@Injectまだ存在しない場合に自分自身に追加できるクラスであるとあえて言いたいと思います。@Injectアノテーション用の軽量標準 Java ライブラリー (JSR-330) の存在により、今後、より多くのライブラリーやフレームワークがアノテーション付きコンストラクターをコンポーネントに提供することがさらに容易になります。

インターフェースの複数の実装

修飾子はこれに対する 1 つの解決策であり、ほとんどの場合は問題ありません。ただし、場合によっては、特定の注入されたクラスのパラメーターで修飾子を使用してもうまくいかない何かをしたいことがあります...多くの場合、そのクラスの複数のインスタンスが必要で、それぞれが異なるインターフェイス実装またはインスタンスを使用するためです。Guice はPrivateModules と呼ばれるものでこれを解決します。この点に関してCDIが何を提供しているかはわかりません。しかし、繰り返しになりますが、これは少数派のケースであり、処理できる限り、構成の残りの部分を犠牲にする価値はありません。

于 2011-02-14T18:03:57.707 に答える
10

次の原則があります。構成関連の Bean は XML で定義されます。その他すべて - 注釈付き。

なんで?クラスの構成を変更したくないためです。一方、有効にしたいクラスに@Serviceandを書く方がはるかに簡単です。@Inject

これがテストに干渉することはありません。注釈は、コンテナーによって解析されるメタデータにすぎません。必要に応じて、さまざまな依存関係を設定できます。

CDI については、XML 構成用の拡張機能がありますが、主に注釈を使用していることは間違いありません。それは私が特に好きではないものです。

于 2011-02-14T17:39:11.877 に答える
4

あなたが指摘したように、私は自分のコードを明確にしておくのが好きです。少なくとも私にとっては、IOC の原則では XML の方が優れています。

構成のための依存性注入の基本原則は、アプリケーション オブジェクトは、依存するリソースまたはコラボレーターを検索する責任を負うべきではないということです。代わりに、IoC コンテナーでオブジェクトを構成し、アプリケーション コードからのリソース ルックアップをコンテナーに外部化する必要があります。(EJB を使用しない J2EE 開発 - Rod Johnson - 131 ページ)

繰り返しますが、それは私の視点に過ぎず、そこには原理主義はありません:)

編集:いくつかの有用な議論があります:

于 2011-02-14T17:32:55.240 に答える
4

私の意見では、これは好みの問題です。

1) 私たちのプロジェクト (Spring 3 を使用) では、XML 構成ファイルを構成だけにしたいと考えています。(エンドユーザーの観点から)構成する必要がない場合、または他の問題によりxmlで実行する必要がない場合は、Bean定義/配線をXML構成に入れず、@Autowiredを使用してくださいなど。

2) Spring では、@Qualifier を使用して、インターフェースの特定の実装が複数存在する場合に一致させることができます。はい、これは実際の実装に名前を付ける必要があることを意味しますが、気にしません。

私たちの場合、すべての DI を処理するために XML を使用すると、XML 構成ファイルが大量に肥大化しますが、別の xml ファイル (または複数のファイル) で実行できるため有効なポイントではありません;)。私が言ったように、それは好みの問題であり、アノテーションを介して注入を処理する方が簡単でクリーンだと思います(XMLファイルを調べるのではなく、クラスを見るだけで、サービス/リポジトリ/何かが使用するものを確認できますbean-declaration を探します)。

編集: @Autowired と XML について、私が完全に同意する意見があります: Spring @Autowired の使用法

于 2011-02-14T17:38:04.017 に答える
3

「しかし、xml のどこが悪いのでしょうか?」これは管理すべきファイルであり、バグを探す場所でもあります。注釈がコードのすぐ隣にあれば、管理とデバッグがはるかに簡単になります。

于 2011-02-14T18:42:13.163 に答える
2

すべてのものと同様に、依存性注入は適度に使用する必要があります。さらに、インジェクションのすべてのトラップは、アプリケーションコードから分離し、mainに関連付けられたコードに追いやる必要があります。

一般に、アプリケーションには、抽象的なアプリケーションコードを具体的な実装の詳細から分離する境界が必要です。その境界を越えるすべてのソースコードの依存関係は、アプリケーションを指している必要があります。その境界の具体的な側面をメインパーティションと呼びます。これは、「メイン」(またはそれに相当するもの)が存在する場所だからです。

メインパーティションは、ファクトリ実装、戦略実装などで構成されています。依存性注入フレームワークが機能するのは、境界のこちら側です。次に、これらの注入された依存関係は、通常の方法で境界を越えてアプリケーションに渡すことができます。(例えば、引数として)。

注入される依存性の数は比較的少なくする必要があります。ダース以下。その場合、XMLとアノテーションのどちらを選ぶかは重要ではありません。

于 2012-06-14T15:31:26.967 に答える
1

私の場合、アプリケーションを書いている開発者はそれを構成している開発者とは異なり (異なる部門、異なるテクノロジ/言語)、最後のグループはソース コードにアクセスすることさえできません (これは多くのエンタープライズ セットアップの場合です)。アプリを実装する開発者によって構成された xml を使用するのではなく、ソース コードを公開する必要があるため、Guice は使用できなくなります。

全体として、コンポーネントの提供とアプリケーションのアセンブル/構成は 2 つの異なる作業であることを認識し、必要に応じてこの関心の分離を提供することが重要だと思います。

于 2011-02-23T04:03:07.440 に答える
1

また、Spring JavaConfig も忘れないでください。

于 2011-02-14T17:40:02.177 に答える
0

すでにここにあるものに追加することがいくつかあります。

  • 私にとって、DI構成はコードです。私はそれをそのように扱いたいのですが、XMLの性質自体が、追加のツールなしではこれを防ぎます。

  • Spring JavaConfigは、この点で大きな前進ですが、それでも複雑な問題があります。コンポーネントのスキャン、インターフェイス実装の自動魔法選択、および@Configuration注釈付きクラスのCGLIBインターセプトに関するセマンティクスにより、必要以上に複雑になります。しかし、それはまだXMLからの一歩です。

  • IoCメタデータをアプリケーションオブジェクトから分離することの利点は、特にSpringでは誇張されています。おそらく、Spring IoCコンテナのみに限定した場合、これは真実です。ただし、Springは、IoCコンテナー(セキュリティ、Web MVCなど)上に構築された幅広いアプリケーションスタックを提供します。そのいずれかを活用するとすぐに、とにかくコンテナに縛られます。

于 2012-04-01T22:37:16.610 に答える
0

XMLには、アプリケーション コード自体から明確に分離して定義された宣言型スタイルという唯一の利点があります。それはDIの懸念から独立したままです。欠点は、冗長性、リファクタリングの堅牢性の低さ、および一般的な実行時障害動作です。Java などの IDE サポートと比較して、ほとんどメリットのない一般的な (XML) ツール サポートがあります。さらに、この XML にはパフォーマンスのオーバーヘッドが伴うため、通常はコード ソリューションよりも遅くなります。

アプリケーション コードをリファクタリングする場合、アノテーションはより直感的で堅牢であるとよく言われます。また、guice が提供するような優れた IDE ガイダンスの恩恵も受けます。しかし、アプリケーション コードと DI の問題が混在しています。アプリケーションはフレームワークに依存します。明確な分離はほとんど不可能です。同じ場所 (コンストラクター、フィールド) で他の状況 (ロボットの脚の問題など) に応じて異なる注入動作を記述する場合、注釈も制限されます。さらに、外部クラス (ライブラリ コード) を独自のソースのように扱うことはできません。そのため、XML よりも高速に実行されると考えられています。

どちらの手法にも重大な欠点があります。したがって、 Silk DIを使用することをお勧めします。これはコードで定義された宣言型 (優れた IDE サポート) ですが、アプリケーション コードからは 100% 分離されています (フレームワークに依存しません)。ソースまたは外部ライブラリからのものであっても、すべてのコードを同じように扱うことができます。ロボットの足の問題のような問題は、通常のビンディングで簡単に解決できます。さらに、ニーズに合わせて調整するための優れたサポートもあります。

于 2012-12-09T14:55:17.933 に答える