@Resourceと@Autowired


380

@Resourcejsr250)または@Autowired(Spring固有)のどのアノテーションをDIで使用する必要がありますか?

私は過去に両方をうまく使用したことが@Resource(name="blah")あり、@Autowired @Qualifier("blah")

@Resourcejsrの人々によって承認されているので、私の本能はタグを守ることです。
誰もがこれについて強い考えを持っていますか?


FYI-私は「アップデート」を削除しました、それは別の質問として尋ねられるべきでした。この拒否されたコメントによると、「この編集は投稿の本来の意図から逸脱しています。大幅な変更を加える必要がある編集でも、投稿の所有者の目標を維持するよう努めるべきです」
mlo55

回答:


194

3.0より前の春には、どちらでもかまいません。

Spring 3.0では、標準(JSR-330)アノテーションがサポートされています@javax.inject.Inject-と組み合わせて使用​​し@Qualifierます。Springが@javax.inject.Qualifierメタ注釈もサポートするようになりました:

@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}

だからあなたは持つことができます

<bean class="com.pkg.SomeBean">
   <qualifier type="YourQualifier"/>
</bean>

または

@YourQualifier
@Component
public class SomeBean implements Foo { .. }

その後:

@Inject @YourQualifier private Foo foo;

これにより、文字列名の使用が減り、スペルミスが発生しやすく、保守が難しくなります。


元の質問については、両方とも、アノテーションの属性を指定せずに、タイプごとに注入を実行します。違いは次のとおりです。

  • @Resource 注入されたBeanの名前を指定できます
  • @Autowired 非必須としてマークできます。

これはばかげた質問のように見えるかもしれませんが、このスタイルのインジェクションを使用する場合、パラメーター付きのパブリックセッターfooまたはコンストラクターが必要ですか?SomeBeanFoo
Snekse

@Snekseは-私の答えを得た:stackoverflow.com/questions/3536674/...
Snekseを

いいえ。あなたはそれを必要としません。フィールドだけ。(春はリフレクションを介してそれを
埋めます

この答えは、実際の違いを示していない@Bozho @Resource@Autowired、実際の答えは@Ichthyoによって掲示一つであり、私はこの1つが更新されなければならないと思います。
ボリストロイホフ

1
はい。実際、私は時々、アプローチのより良い代替案を提供することによって質問に答えます。しかし、完全を
期す

509

両方@Autowired(または@Inject)と@Resource同等にうまく機能します。しかし、概念的な違いや意味の違いがあります

  • @Resource名前で既知のリソースを取得することを意味します。名前は、注釈付きセッターまたはフィールドの名前から抽出されるか、name-Parameterから取得されます。
  • @Injectまたは、タイプ別に適切な他のコンポーネント@Autowiredを配線してみます。

つまり、基本的にこれらは2つのまったく異なる概念です。残念ながら、のSpring-Implementationに@Resourceは組み込みのフォールバックがあり、名前による解決が失敗すると起動します。この場合、@Autowiredタイプごとの-kind resolutionにフォールバックします。このフォールバックは便利ですが、IMHOは概念の違いを認識しておらず、@Resourceタイプベースの自動配線に使用する傾向があるため、多くの混乱を引き起こします。


81
はい、これは受け入れられるべき答えです。たとえば、@Resource注釈付きフィールドがあり、フィールド名がコンテナ内のBeanのIDと一致するorg.springframework.beans.factory.BeanNotOfRequiredTypeException場合、タイプが異なる場合、Springはスロー します。これは、Beanが最初に@Resourceタイプではなく、注釈内の名前で一致するためです。ただし、プロパティの名前がBeanの名前と一致しない場合、Springはタイプによってそれらをワイヤリングします。
ボリストロイホフ

単純なMAPを使用しようとしたときに、この2つの違いを説明する他の投稿を参照できます。stackoverflow.com/questions/13913752/…–
アンバーサドハット2013

4
+1は、受け入れられた回答のようにまったく異なる「ベストプラクティス」を単に推奨するのではなく、実際に質問に回答するためのものです。私も参考、3つのすべての注釈スタイルでいくつかの一般的なシナリオのかを示した結果、このブログの記事を見つけました:blogs.sourceallies.com/2011/08/...
ジュール・

1
読者の方は、@ Julesが指摘した記事の概要をここで見つけてください:stackoverflow.com/a/23887596/363573
Stephan

3
これが意味することの1つは、Map / List Beanをインジェクトしたい場合、機能し@Autowireない、または機能しないことです。@Resourceその場合は使用する必要があります。
Ricardo van den Broek

76

主な違いは、@Autowired春の注釈です。一方@Resource、あなた自身が指摘したように、JSR-250によって指定されています。したがって、後者はJavaの一部ですが、前者はSpring固有です。

したがって、あなたはある意味でそれを示唆するのは正しいです。より強力なため、人々がで使用@Autowiredして@Qualifierいるのを発見しました。あるフレームワークから別のフレームワークに移動することは、特にSpringの場合、神話ではないにしても、非常にまれであると考えられています。


7
1、ため@Autowired@Qualifier本当にある JSR標準よりも強力な@Resource注釈(と例えば、オプションの依存関係を考える@Autowired(required=false)あなたが持つことはできません。@Resource
ステファンHaberl

70

私はからの1件のコメントを強調したいと思います@Julesをこの答えこの質問へ。コメントには便利なリンクが表示されます。@ Resource、@ Autowired、@ Injectを使用したSpringインジェクションです。完全に読むことをお勧めしますが、その有用性の簡単な要約を以下に示します。

アノテーションはどのようにして適切な実装を選択しますか?

@Autowired そして @Inject

  1. タイプによる一致
  2. 修飾子による制限
  3. 名前で一致

@Resource

  1. 名前で一致
  2. タイプによる一致
  3. 修飾子による制限(名前で一致が見つかった場合は無視されます)

Beanの注入に使用する注釈(またはその組み合わせ)はどれですか?

  1. コンポーネントに明示的に名前を付けます[@Component( "beanName")]

  2. 属性[@Resource(name = "beanName")] @Resourceとともに使用しnameます

なぜ使用しないの@Qualifierですか?

@Qualifier同様のBeanのリストを作成する場合を除き、注釈は避けてください。たとえば、一連のルールに特定の@Qualifier注釈を付けることができます。このアプローチにより、ルールクラスのグループを、データの処理に使用できるリストに簡単に挿入できます。

Beanインジェクションはプログラムを遅くしますか?

コンポーネントの特定のパッケージをスキャンします[context:component-scan base-package="com.sourceallies.person"]。これによりcomponent-scan構成が増える一方で、不要なコンポーネントをSpringコンテキストに追加する可能性が低くなります。


リファレンス: @ Resource、@ Autowired、@ Injectを使用したSpringインジェクション


39

これは私がSpring 3.0.xリファレンスマニュアルから得たものです:-

ヒント

アノテーション駆動型の注入を名前で表現する場合は、技術的に@Qualifier値を通じてBean名を参照できる場合でも、主に@Autowiredを使用しないでください。代わりに、意味的に定義されているJSR-250 @Resourceアノテーションを使用して、特定のターゲットコンポーネントを一意の名前で識別します。宣言された型はマッチングプロセスには関係ありません。

このセマンティックの違いの具体的な結果として、コレクションまたはマップタイプとして定義されているBeanは、タイプマッチングが適切に適用されないため、@ Autowiredを介して注入できません。そのようなBeanには@Resourceを使用し、固有の名前で特定のコレクションまたはマップBeanを参照します。

@Autowiredはフィールド、コンストラクター、および複数引数のメソッドに適用され、パラメーターレベルで修飾子アノテーションを絞り込むことができます。対照的に、@ Resourceは、単一の引数を持つフィールドおよびBeanのプロパティセッターメソッドでのみサポートされます。結果として、注入ターゲットがコンストラクターまたは複数引数メソッドの場合は、修飾子を使用します。


現在のバージョンについては、docs.spring.io / spring / docs / current / spring
framework

28

@Autowired + @Qualifierは、将来、他のDIを使用する場合、Spring DIでのみ機能します。@ Resourceが適切なオプションです。

@Qualifierはプレースホルダーをサポートしていないので、@ Qualifierは動的Beanのワイヤリングをサポートしていませんが、@ Resourceは非常にうまく機能しています。

例:このような複数の実装を持つインターフェースがある場合

interface parent {

}
@Service("actualService")
class ActualService implements parent{

}
@Service("stubbedService")
class SubbedService implements parent{

}

@Autowiredと@Qualifierでは、次のような特定の子実装を設定する必要があります

@Autowired
@Qualifier("actualService") or 
@Qualifier("stubbedService") 
Parent object;

これはプレースホルダーを提供しませんが、@ Resourceを使用すると、プレースホルダーを配置し、プロパティファイルを使用して特定の子の実装を注入できます。

@Resource(name="${service.name}")
Parent object;  

ここで、service.nameはプロパティファイルで次のように設定されています。

#service.name=actualService
 service.name=stubbedService

それが誰かを助けることを願っています:)


16

それらの両方は同等に良いです。Resourceを使用する利点は、春以外の別のDIフレームワークが必要な場合に、コードの変更がはるかに簡単になることです。Autowiredを使用すると、コードがSprings DIと緊密に結合されます。


17
あり得ない。そして、たとえそうであったとしても、アノテーション名で検索/置換を行うことは、あなたの問題の最小のものになるでしょう。
Daniel Alexiuc 2015年

13

これら2つのアノテーションの基本クラスから批判的に分析すると、次の違いがわかります。

@AutowiredAutowiredAnnotationBeanPostProcessor 依存関係を注入するために使用します。依存関係を注入
@ResourceするCommonAnnotationBeanPostProcessorために使用します。

異なるポストプロセッサクラスを使用していますが、動作はほぼ同じです。違いは、実行パスにあります。これについては、以下で強調します。

@Autowired / @Inject

1.タイプによる
一致2.修飾
子による制限3.名前による一致

@Resource

1.名前による
一致2.タイプ
による一致3.修飾子による制限(名前で一致が見つかった場合は無視されます)


6

@Resourceあなたは豆の自己注射を行うことができ、それは、トランザクションやセキュリティ関連のもののような豆のポストプロセッサによって追加されたすべての余分なロジックを実行するために必要になる場合があります。

Spring 4.3以降で@Autowiredは、これを行うこともできます。


2

@Resource多くの場合、JNDIを介して定義された高レベルオブジェクトによって使用されます。@Autowiredまたは@Inject、より一般的なBeanで使用されます。

私の知る限り、これは仕様ではなく、慣例でもありません。これは、標準コードがこれらの注釈を使用するより論理的な方法です。


0

ここでのメモとして: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContextと 注釈では機能しSpringBeanAutowiringSupport.processInjectionBasedOnServletContext ません@Resource。したがって、違いがあります。

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