どのアノテーション、@リソース( jsr250 )または@ Autowired(Spring-specific)私はDIで使うべきですか?
私は過去に@Resource(name="blah")
と@Autowired @Qualifier("blah")
の両方をうまく使ったことがあります。
それはjsrの人々によって承認されているので、私の本能は@Resource
タグに固執することです。
誰もがこれについて強い考えを持っていますか?
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
では、これを必須ではないとマークすることができます。@Autowired
(または@Inject
)と@Resource
はどちらも同じように機能します。しかし、概念的な違いや意味の違いがあります
@Resource
は既知のリソースを名前で取得することを意味します。名前は、注釈付きの設定者またはフィールドの名前から抽出されるか、name-Parameterから取得されます。@Inject
または@Autowired
は、適切な他のコンポーネントをタイプで接続しようとします。つまり、基本的にこれらはまったく異なる2つの概念です。残念ながら、@Resource
のSpring実装には組み込みのフォールバックがあります。これは名前による解決が失敗したときに始まります。この場合、タイプ別の@Autowired
-kind解決にフォールバックします。このフォールバックは便利ですが、私たちは多くの混乱を招きます。なぜなら、人々は概念の違いに気付いておらず、型ベースの自動配線に@Resource
を使用する傾向があるからです。
主な違いは、@Autowired
は春の注釈です。あなた自身が指摘したように、@Resource
はJSR-250によって指定されています。したがって、後者はJavaの一部ですが、前者はSpring固有のものです。
したがって、ある意味で、あなたはそれを示唆しているのです。私は人々が@Autowired
と@Qualifier
を一緒に使っているのを見つけました。特にSpringの場合、あるフレームワークから他のフレームワークへの移行は、神話ではないにしても、非常にありそうにないと考えられます。
@ Jules on この質問へのコメント から1つのコメントを強調したいと思います。コメントには便利なリンクがあります: @Resource、@ Autowired、@ Inject によるSpring Injection。全部読むことをお勧めしますが、ここではその有用性について簡単に要約します。
@Autowired
と@Inject
@Resource
コンポーネントに明示的に名前を付ける[@Component( "beanName")]
name
属性を持つ@Resource
を使用します[@Resource(name = "beanName")]
@Qualifier
を使わないのですか?類似のBeanのリストを作成したいのでなければ、@Qualifier
アノテーションは避けてください。たとえば、一連のルールに特定の@Qualifier
アノテーションを付けたい場合があります。この方法では、データ処理に使用できるリストにルールクラスのグループを簡単に挿入できます。
特定のパッケージをスキャンしてコンポーネント[context:component-scan base-package="com.sourceallies.person"]
を探します。これによりcomponent-scan
設定が増えますが、不要なコンポーネントをSpringのコンテキストに追加する可能性が低くなります。
これは、 Spring 3.0.xリファレンスマニュアル から得たものです。 -
先端
アノテーションドリブンのインジェクションを名前で表現するつもりなら、たとえ技術的に@Qualifier値を通してbean名を参照することができるとしても、主に@Autowiredを使わないでください。代わりに、JSR-250の@Resourceアノテーションを使用してください。これは、固有の名前で特定のターゲットコンポーネントを識別するために意味的に定義されています。宣言された型はマッチングプロセスには関係ありません。
この意味の違いの具体的な結果として、それ自体はコレクション型またはマップ型として定義されているBeanは、@Autowiredを介して注入することはできません。そのようなBeanには@Resourceを使用し、固有の名前で特定のコレクションまたはマップBeanを参照します。
@Autowiredはフィールド、コンストラクタ、および複数引数メソッドに適用され、パラメータレベルでの修飾子アノテーションによる絞り込みを可能にします。対照的に、@Resourceは単一の引数を持つフィールドとBeanプロパティセッターメソッドでのみサポートされています。結果として、あなたのインジェクションターゲットがコンストラクタであるかマルチ引数メソッドであるならば、修飾子を使い続けてください。
@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
誰かに役立つことを願っています:)
どちらも同等に優れています。 Spring以外の別のDIフレームワークを使用したい場合は、Resourceを使用する利点が今後あります。コードの変更ははるかに簡単になります。 Autowiredを使用すると、コードはスプリングDIと密接に関連しています。
これら2つのアノテーションの基本クラスから批判的に分析すると、次のような違いがわかります。
@Autowired
はAutowiredAnnotationBeanPostProcessor
を使って依存関係を注入します。@Resource
はCommonAnnotationBeanPostProcessor
を使って依存関係を注入します。
異なるポストプロセッサクラスを使用していても、それらはすべてほぼ同じように動作します。違いは、実行パスに大きく左右されます。これについては、以下で強調します。
@Autowired / @Inject
タイプ別1.Matches
2.予選による制限
3.名前による一致
@Resource
名前による1.Matches
2.タイプ別一致
3.限定子による制限(名前で一致が見つかった場合は無視されます)
@Resource
を使用すると、Beanの自己注入を実行できます。トランザクション関連やセキュリティ関連など、Beanポストプロセッサによって追加されたすべての追加ロジックを実行するために必要になる場合があります。
Spring 4.3以降では、@Autowired
もこれを実行できます。
@Resource
は、JNDIを介して定義された高水準オブジェクトによってしばしば使用されます。 @Autowired
または@Inject
は、より一般的なBeanによって使用されます。
私の知る限りでは、それは仕様でも慣習でもありません。標準的なコードがこれらのアノテーションを使うより論理的な方法です。
ここで注意してください:SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
とSpringBeanAutowiringSupport.processInjectionBasedOnServletContext
は@Resource
アノテーションでは動作しません。それで、違いがあります。