@Resource(jsr250)または@Autowired(Spring固有)のどのアノテーションをDIで使用する必要がありますか?
私は過去に両方をうまく使用したことが@Resource(name="blah")
あり、@Autowired @Qualifier("blah")
@Resource
jsrの人々によって承認されているので、私の本能はタグを守ることです。
誰もがこれについて強い考えを持っていますか?
@Resource(jsr250)または@Autowired(Spring固有)のどのアノテーションをDIで使用する必要がありますか?
私は過去に両方をうまく使用したことが@Resource(name="blah")
あり、@Autowired @Qualifier("blah")
@Resource
jsrの人々によって承認されているので、私の本能はタグを守ることです。
誰もがこれについて強い考えを持っていますか?
回答:
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
またはコンストラクターが必要ですか?SomeBean
Foo
@Resource
と@Autowired
、実際の答えは@Ichthyoによって掲示一つであり、私はこの1つが更新されなければならないと思います。
両方@Autowired
(または@Inject
)と@Resource
同等にうまく機能します。しかし、概念的な違いや意味の違いがあります
@Resource
名前で既知のリソースを取得することを意味します。名前は、注釈付きセッターまたはフィールドの名前から抽出されるか、name-Parameterから取得されます。@Inject
または、タイプ別に適切な他のコンポーネント@Autowired
を配線してみます。つまり、基本的にこれらは2つのまったく異なる概念です。残念ながら、のSpring-Implementationに@Resource
は組み込みのフォールバックがあり、名前による解決が失敗すると起動します。この場合、@Autowired
タイプごとの-kind resolutionにフォールバックします。このフォールバックは便利ですが、IMHOは概念の違いを認識しておらず、@Resource
タイプベースの自動配線に使用する傾向があるため、多くの混乱を引き起こします。
@Resource
注釈付きフィールドがあり、フィールド名がコンテナ内のBeanのIDと一致するorg.springframework.beans.factory.BeanNotOfRequiredTypeException
場合、タイプが異なる場合、Springはスロー します。これは、Beanが最初に@Resource
タイプではなく、注釈内の名前で一致するためです。ただし、プロパティの名前がBeanの名前と一致しない場合、Springはタイプによってそれらをワイヤリングします。
@Autowire
ない、または機能しないことです。@Resource
その場合は使用する必要があります。
主な違いは、@Autowired
春の注釈です。一方@Resource
、あなた自身が指摘したように、JSR-250によって指定されています。したがって、後者はJavaの一部ですが、前者はSpring固有です。
したがって、あなたはある意味でそれを示唆するのは正しいです。より強力なため、人々がで使用@Autowired
して@Qualifier
いるのを発見しました。あるフレームワークから別のフレームワークに移動することは、特にSpringの場合、神話ではないにしても、非常にまれであると考えられています。
@Autowired
に@Qualifier
本当にある JSR標準よりも強力な@Resource
注釈(と例えば、オプションの依存関係を考える@Autowired(required=false)
あなたが持つことはできません。@Resource
)
私はからの1件のコメントを強調したいと思います@Julesを上この答えこの質問へ。コメントには便利なリンクが表示されます。@ Resource、@ Autowired、@ Injectを使用したSpringインジェクションです。完全に読むことをお勧めしますが、その有用性の簡単な要約を以下に示します。
@Autowired
そして @Inject
@Resource
コンポーネントに明示的に名前を付けます[@Component( "beanName")]
属性[@Resource(name = "beanName")] @Resource
とともに使用しname
ます
@Qualifier
ですか?@Qualifier
同様のBeanのリストを作成する場合を除き、注釈は避けてください。たとえば、一連のルールに特定の@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を使用する場合、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
それが誰かを助けることを願っています:)
それらの両方は同等に良いです。Resourceを使用する利点は、春以外の別のDIフレームワークが必要な場合に、コードの変更がはるかに簡単になることです。Autowiredを使用すると、コードがSprings DIと緊密に結合されます。
これら2つのアノテーションの基本クラスから批判的に分析すると、次の違いがわかります。
@Autowired
AutowiredAnnotationBeanPostProcessor
依存関係を注入するために使用します。依存関係を注入
@Resource
するCommonAnnotationBeanPostProcessor
ために使用します。
異なるポストプロセッサクラスを使用していますが、動作はほぼ同じです。違いは、実行パスにあります。これについては、以下で強調します。
@Autowired / @Inject
1.タイプによる
一致2.修飾
子による制限3.名前による一致
@Resource
1.名前による
一致2.タイプ
による一致3.修飾子による制限(名前で一致が見つかった場合は無視されます)
と @Resource
あなたは豆の自己注射を行うことができ、それは、トランザクションやセキュリティ関連のもののような豆のポストプロセッサによって追加されたすべての余分なロジックを実行するために必要になる場合があります。
Spring 4.3以降で@Autowired
は、これを行うこともできます。