Spring @Autowiredの使用


218

Springによってワイヤリングされるクラスで@Autowiredを使用することの長所と短所は何ですか?

明確にするために、私は特に@Autowiredアノテーションについて話しているのであって、XMLでの自動配線については話していません。

おそらく私はそれを理解していないだけですが、私にはそれはほとんどアンチパターンのように見えます-クラスは、POJOであるだけでなく、DIフレームワークに関連付けられていることに気づき始めます。たぶん私は罰の大食いですが、私はBeanの外部XML設定が好きで、明示的な配線をしたいので、どこに何が配線されているかを正確に把握しています。


4
私もこのテーマに興味があります。XMLではなくアノテーションを使用してMVCアプリを構成すると、「このクラスはこのURLにマッピングされていますか?」という多くの検索につながるようです。「誰がこれを扱っているのですか?」単一の構成ソースが
欲しい

6
「@Autowiring」という用語は、ここでは誤解を招くようです。XML構成を使用して自動配線を行うこともできるため、元の質問は「Springアノテーションを使用する場合の長所と短所」と言い換える必要があります。提供されている答えは、自動配線の側面に重点を置いており、注釈の使用の側面には重点を置いていません。
Neeme Praks、2009年

回答:


253

私は長い間、私たち全員が使用していたxmlファイルのような「集中型の宣言型構成」を持つことに価値があると信じていました。その後、ファイルの内容のほとんどが構成ではないことに気付きました。開発後、変更されることはありません。次に、「集中型」は非常に小さなシステムでのみ価値があることに気づきました-小さなシステムでのみ、全体として構成ファイルを見ることができます。そして、同じ「配線」がコード内の依存関係によってほとんど複製される場合、実際に配線全体を理解することの価値は何ですか?したがって、私が保持しているのは、メタデータ(注釈)だけです。これは、まだ宣言型です。これら実行時に変更されることはなく、 誰かがその場で変更する「構成」データ-コードに保持するのは良いことだと思います。

可能な限りフルオートワイヤリングを使用しています。大好きです。銃を突きつけられないと脅されない限り、私は古いスタイルの春には戻りません。私が完全に好む理由は@Autowired、時とともに変わってきました。

現在、自動配線を使用する最も重要な理由は、追跡するシステムの抽象化が1つ少ないことです。「豆の名前」は事実上なくなりました。xmlのため、Bean名のみが存在することがわかりました。そのため、抽象インダイレクションの完全なレイヤー(Bean名「foo」をBean「bar」にワイヤリングする場所)はなくなりました。ここで、「Foo」インターフェースをBeanに直接配線し、実行時プロファイルによって実装を選択します。これにより、依存関係と実装をトレースするときにコードを操作できます。コードにautowired依存関係が表示されたら、IDEで「実装に移動」キーを押すだけで、既知の実装のリストが表示されます。ほとんどの場合、実装は1つしかなく、私はクラスにまっすぐ入っています。できる' どの実装が使用されているか(XMLワイヤリングを使用すると、その逆は真実に近いと私は主張します-あなたの視点がどのように変化するのか面白いです!)

これは非常に単純なレイヤーと言えますが、システムに追加する抽象化の各レイヤーは複雑さを増します。私が実際に使用したシステムにxmlが実際の価値を追加したことはないと思います。

私がこれまでに使用したほとんどのシステムには、実稼働ランタイム環境の構成が1つしかありません。テストなどの他の構成がある場合があります。

完全自動配線は春のルビーオンレールであると思います。ほとんどのユースケースが従う通常の一般的な使用パターンがあるという概念を採用しています。XML構成を使用すると、意図的または意図的でない多くの一貫した/一貫性のない構成の使用を許可できます。あまりにも多くのxml構成が矛盾して行き過ぎているのを見てきました-コードと一緒にリファクタリングされますか?考えていません。理由のためにそれらのバリエーションはありますか?通常はありません。

構成では修飾子をほとんど使用せず、これらの状況を解決する他の方法を見つけました。これは、私たちが遭遇する明らかな「欠点」です。自動配線との相互作用をよりスムーズにするために、コードの方法を少し変更しました。顧客リポジトリは、汎用Repository<Customer>インターフェースを実装しなくなりましたがCustomerRepository、拡張するインターフェースを作成しますRepository<Customer>。サブクラス化に関しては、1つまたは2つのトリックがある場合もあります。しかし、それは通常、より強いタイピングの方向を示すだけであり、ほとんどの場合、これはより良い解決策だと私は思います。

しかし、はい、あなたは主に春がする特定のスタイルのDIに縛られています。依存関係のパブリックセッターも作成しなくなりました(カプセル化/情報非表示部門で+1していると主張できます)まだシステムにxmlがありますが、xmlには基本的に異常のみが含まれています。完全自動配線はxmlとうまく統合されます。

私たちが今必要とする唯一のものは用で@Component@Autowired残りは(のようなJSRに含まれるJSR-250、我々は春とで結ぶ必要はありませんので、)。これは過去に起こった方法です(java.util.concurrent思い浮かぶことがあるので)。これが再び起こったとしても、私はまったく驚かないでしょう。


5
javax.annotation / javax.injectはSpringでサポートされているため、Springにコードの依存関係を持たせる必要はありません。
Michael Wiles

26

私にとって、ここでは、Springと自動配線の好きなところと嫌いなところがあります。

長所:

  • 自動配線は厄介なXML構成を取り除きます。
  • フィールド、セッターメソッド、またはコンストラクターを使用して直接注入できるアノテーションを使用する方がはるかに簡単です。また、注入されたBeanに注釈を付けて「修飾」することもできます。

短所:

  • 自動配線と注釈を使用すると、Springライブラリに依存するようになります。XML構成と同様に、Springの有無にかかわらず実行できます。あなたが言ったように、あなたはDIフレームワークに縛られるようになります。
  • 同時に、私はBeanを「修飾」できることが好きです。これにより、コードが本当に面倒になります。同じBeanを複数の場所に挿入する必要がある場合は、同じ文字列名がすべて繰り返されるのを見ました。私にはこれがエラーの可能性があるようです。

とにかくSpringの統合に依存しすぎているため、依存関係の問題が解決されていないため、仕事でほぼ完全に自動配線を使い始めました。私は広範囲に自動配線を使用するSpring MVCプロジェクトに取り組み、頭を回すのが少し困難でした。

私は自動配線は慣れ親しんだ味だと思います。慣れると、XML構成よりも強力で簡単で、頭痛の種が少ないことを実感できます。


3
オートコンプリート、Beanグラフなどを備えた無料のSpringsource Tool Suiteを使用すると、xml構成がそれほど厄介でなくなる
Sean Patrick Floyd

自動配線が煩雑になり、春のライブラリに依存することについては、あなたに全く同意します!私はXML構成を使用したことがなく、おそらくその道を進むべきだと思いますか?
James111

15

私たちの大きなプロジェクトでは、@ AutowireからXML構成に切り替えています。問題は、ブートストラップのパフォーマンスが非常に低いことです。自動配線スキャナーは自動配線検索クラスパスからすべてのクラスをロードするため、Springの初期化中に多くのクラスが熱心に読み込まれます。


1
私はjavaconfigが部分的なコンテキストを開始するためのより良い解決策であるかもしれないことを発見しました、それは大きな勝利です。
krosenvold 2013

6

環境の切り替えについてはほとんど議論されていません。私が取り組んだほとんどのプロジェクトは、私たちが取り組んでいる環境に応じて依存関係を注入することは実際の問題でした。xml configを使用すると、Spring ELを使用するのは非常に簡単です。アノテーションを使用した優れたソリューションはありません。私は1つを見つけました:

    @Value("#{${env} == "production" ? realService : dummyService}")
    private SomeService service;

それは機能しているはずですが、素晴らしいソリューションではありません。


私はこれについて別のスレッドを開いて、春と解決策があり@Profilesかつ@Configurationblog.springsource.org/2011/02/14/... も他のスレッドを参照してください:stackoverflow.com/questions/13490393/...を
BTakacs

4

@Autowireに切り替えました。小規模なプロジェクト以外でXML構成を維持することは、それ自体がタスクとなり、理解力が急速に低下しました。

IntelliJは、Springアノテーションに対して優れた(完全ではない)サポートを提供します。


3

この問題についての私の見解は、特に大規模なシステムでは、xml構成によってコードの明瞭さが低下するということです。

@Componentのような注釈は事態をさらに悪化させます。デフォルトのコンストラクターを提供する必要があるとすれば、依存関係を最終的なものにすることができなくなるため、オブジェクトを変更可能にするよう開発者に働きかけます。依存関係は、パブリックセッターを通じて挿入するか、@ Autowiredを通じて制御しないようにする必要があります。[さらに悪い依存関係の注入は、依存関係をインスタンス化するクラスで危険にさらされていますが、私はまだこれを新しく書かれたコードで見ます!]。制御されていないということは、つまり、大規模なシステムでは、タイプの複数の実装(または子)が利用可能な場合、どの実装が@Autowiredであったかを理解することは非常に複雑になり、バグの調査がはるかに困難になります。また、テスト環境用のプロファイルと本番用のプロファイルがあると考えられます。

私は自分の構成クラスを宣言する中間点に固執します(@Configurationを使用したJavaベースのSpring構成)

すべてのBeanを構成クラスで明示的に宣言します。@Autowiredは構成クラスでのみ使用します。目的は、Springへの依存を構成クラスに制限することです。

@Configurationは特定のパッケージにあります。これは、スプリングスキャンが実行される唯一の場所です。(これにより、大規模プロジェクトの開始時間が大幅に短縮されます)

私はすべてのクラス、特にデータオブジェクト、JPA、Hibernate、およびSpringを不変にするよう努めており、多くのシリアル化ライブラリがこれを弱体化させているようです。私はセッターの提供を強制するものから離れるか、またはプロパティ宣言から最後のキーワードを削除します。

オブジェクトの作成後にオブジェクトを変更する可能性を減らし、大規模なシステムのバグを大幅に減らし、バグが存在する場合にバグを見つけるまでの時間を短縮します。

また、システムの異なる部分間の相互作用をよりよく設計することを開発者に強いているようです。問題やバグはますますコンパイルエラーになり、無駄な時間を減らして生産性を向上させます。


1

ここでの経験の一部です
賛否

  • @Autowireアノテーションのみを使用できるため、構成が簡単になります。
  • セッターメソッドを使用したくないので、クラスはよりクリーンになります

短所

  • DIを使用している場合でも、xmlファイルに密結合する
  • 実装を見つけるのは難しい(しかし、あなたがintellijのような良いIDEを使用している場合は、これを取り除くことができるでしょう)

私の個人的な経験では、@ AutoWireアノテーションをあまり使用しませんでしたが、テストケースで使用しました。


1

XMLの代わりに、注釈を使って書くことが本当に大好きです。Springマニュアルと以前のバージョンによれば、XMLとAnnotationは同じ結果を達成しました。

これは私のリストです

プロ:

  • XMLから不要な行を削除する
  • コードのデバッグを簡略化する:クラスを開くと、クラスにあるものを読み取ることができます
  • より迅速な開発、400行以上のXMLを含むプロジェクトは読み取り可能ですか?

短所:

  • 標準のJava実装ではありませんが、Java標準APIである@Injectを使用するように切り替えることができるため、BeanはPojoのままです
  • あなたは単にどこでも、db接続などを使用することはできませんが、それは意見です。私はすべての設定を読む場所があることを好みます。

0

私の理解では、インターフェース参照を参照し、そのオーバーライド関数を使用するときに@Autowiredが最適ですが、実行時にnullに割り当てられることがあるという問題があるだけです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.