web-dev-qa-db-ja.com

@Resourceと@Autowired

どのアノテーション、@リソースjsr250 )または@ Autowired(Spring-specific)私はDIで使うべきですか?

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

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

334
mlo55

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

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では、これを必須ではないとマークすることができます。
174
Bozho

@Autowired(または@Inject)と@Resourceはどちらも同じように機能します。しかし、概念的な違いや意味の違いがあります

  • @Resource既知のリソースを名前で取得することを意味します。名前は、注釈付きの設定者またはフィールドの名前から抽出されるか、name-Parameterから取得されます。
  • @Injectまたは@Autowiredは、適切な他のコンポーネントをタイプで接続しようとします。

つまり、基本的にこれらはまったく異なる2つの概念です。残念ながら、@ResourceのSpring実装には組み込みのフォールバックがあります。これは名前による解決が失敗したときに始まります。この場合、タイプ別の@Autowired-kind解決にフォールバックします。このフォールバックは便利ですが、私たちは多くの混乱を招きます。なぜなら、人々は概念の違いに気付いておらず、型ベースの自動配線に@Resourceを使用する傾向があるからです。

462
Ichthyo

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

したがって、ある意味で、あなたはそれを示唆しているのです。私は人々が@Autowired@Qualifierを一緒に使っているのを見つけました。特にSpringの場合、あるフレームワークから他のフレームワークへの移行は、神話ではないにしても、非常にありそうにないと考えられます。

72
Adeel Ansari

@ Jules on この質問へのコメント から1つのコメントを強調したいと思います。コメントには便利なリンクがあります: @Resource、@ Autowired、@ Inject によるSpring Injection。全部読むことをお勧めしますが、ここではその有用性について簡単に要約します。

アノテーションはどのように正しい実装を選択しますか?

@Autowired@Inject

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

@Resource

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

私の豆を注入するためにどのアノテーション(あるいはその組み合わせ)を使うべきですか?

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

  2. name属性を持つ@Resourceを使用します[@Resource(name = "beanName")]

なぜ@Qualifierを使わないのですか?

類似のBeanのリストを作成したいのでなければ、@Qualifierアノテーションは避けてください。たとえば、一連のルールに特定の@Qualifierアノテーションを付けたい場合があります。この方法では、データ処理に使用できるリストにルールクラスのグループを簡単に挿入できます。

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

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


参照:@リソース、@自動および@インジェクションによるSpringインジェクション

63
Stephan

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

先端

アノテーションドリブンのインジェクションを名前で表現するつもりなら、たとえ技術的に@Qualifier値を通してbean名を参照することができるとしても、主に@Autowiredを使わないでください。代わりに、JSR-250の@Resourceアノテーションを使用してください。これは、固有の名前で特定のターゲットコンポーネントを識別するために意味的に定義されています。宣言された型はマッチングプロセスには関係ありません。

この意味の違いの具体的な結果として、それ自体はコレクション型またはマップ型として定義されているBeanは、@Autowiredを介して注入することはできません。そのようなBeanには@Resourceを使用し、固有の名前で特定のコレクションまたはマップBeanを参照します。

@Autowiredはフィールド、コンストラクタ、および複数引数メソッドに適用され、パラメータレベルでの修飾子アノテーションによる絞り込みを可能にします。対照的に、@Resourceは単一の引数を持つフィールドとBeanプロパティセッターメソッドでのみサポートされています。結果として、あなたのインジェクションターゲットがコンストラクタであるかマルチ引数メソッドであるならば、修飾子を使い続けてください。

38
Kartik

@Autowired + @Qualifierは、春のDIでのみ機能します。将来他の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

誰かに役立つことを願っています:)

20
Ali

どちらも同等に優れています。 Spring以外の別のDIフレームワークを使用したい場合は、Resourceを使用する利点が今後あります。コードの変更ははるかに簡単になります。 Autowiredを使用すると、コードはスプリングDIと密接に関連しています。

16
Teja Kantamneni

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

@AutowiredAutowiredAnnotationBeanPostProcessorを使って依存関係を注入します。
@ResourceCommonAnnotationBeanPostProcessorを使って依存関係を注入します。

異なるポストプロセッサクラスを使用していても、それらはすべてほぼ同じように動作します。違いは、実行パスに大きく左右されます。これについては、以下で強調します。

@Autowired / @Inject

タイプ別1.Matches
2.予選による制限
3.名前による一致

@Resource

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

6
Amos Kosgei

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

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

4

@Resourceは、JNDIを介して定義された高水準オブジェクトによってしばしば使用されます。 @Autowiredまたは@Injectは、より一般的なBeanによって使用されます。

私の知る限りでは、それは仕様でも慣習でもありません。標準的なコードがこれらのアノテーションを使うより論理的な方法です。

2
Nicolas Zozol

ここで注意してください:SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContextSpringBeanAutowiringSupport.processInjectionBasedOnServletContext@Resourceアノテーションでは動作しません。それで、違いがあります。

0
msangel