Springを使用してアプリケーションを開発しています。 @Service
アノテーションを使用する必要があります。 ServiceImpl implements ServiceI
のようなServiceI
とServiceImpl
があります。ここで@Service
注釈をどこに保持すべきかについて混乱しています。
インターフェイスまたは実装に@Service
で注釈を付ける必要がありますか?これら2つのアプローチの違いは何ですか?
@Component
(または@Service
、...)をインターフェイスに配置したことはありません。インターフェイスが役に立たなくなるからです。理由を説明します。
claim 1:インターフェイスがある場合は、そのインターフェイスを注入ポイントタイプに使用します。
claim 2:インターフェイスの目的は、複数の実装で実装できるコントラクトを定義することです。反対側には、注入ポイント(@Autowired
)があります。インターフェースが1つだけで、それを実装するクラスが1つだけであると(IMHO)役に立たず、 YAGNI に違反します。
fact:置くとき:
@Component
(または@Service
、...)、次にNoUniqueBeanDefinitionException
を取得します(または、環境、プロファイル、または修飾子を使用して、非常に特別な構成をセットアップします...)
結論:インターフェイスで@Component
(または@Service
、...)を使用する場合、少なくとも1つに違反する必要があります2つのクレーンの。したがって、@Component
をインターフェイスレベルに配置することは(いくつかのまれなシナリオを除き)役に立たないと思います。
Spring-Data-JPAリポジトリインターフェースは完全に異なるものです
基本的に @ Service 、 @ Repository 、 @ Component などのアノテーションは、すべて同じ目的を果たします。
注釈ベースの構成およびクラスパススキャンを使用する場合の自動検出。
私の経験から、私は常に、インターフェースに@Service
アノテーションを使用し、実装には@Component
や@Repository
などの抽象クラスとアノテーションを使用しています。 @Component
注釈基本的な目的に役立つクラス、単純なSpring Beanで使用しているもの、それ以上は使用していません。 @Repository
アノテーションは、DAO
レイヤーで使用しています。データベースと通信する必要がある場合、トランザクションがある場合など。
したがって、@Service
および機能に応じて他のレイヤーでインターフェイスに注釈を付けることをお勧めします。
@ Component、@ Service、@ Controller、@ Repositoryアノテーションは、実装クラスでのみ使用し、インターフェイスでは使用しませんでした。しかし、インターフェイスを使用した@Autowiredアノテーションは引き続き機能しました。
@Serviceに注釈を付けることの長所は、それがサービスであるというヒントを与えることです。実装クラスがデフォルトでこの注釈を継承するかどうかはわかりません。
考慮すべき点は、スプリング固有の注釈を使用して、インターフェースを特定のフレームワーク、つまりスプリングと結合していることです。インターフェースは実装から切り離されることになっているため、フレームワーク固有の注釈やインターフェースのオブジェクト部分を使用することはお勧めしません。
Springの利点の1つは、サービス(またはその他の)実装を簡単に切り替えることです。そのためには、インターフェイスに注釈を付けて、次のように変数を宣言する必要があります。
@Autowired
private MyInterface myVariable;
ではなく:
@Autowired
private MyClassImplementationWhichImplementsMyInterface myVariable;
最初のケースと同様に、一意である時点から注入する実装をアクティブ化できます(インターフェイスを実装するクラスは1つだけです)。 2番目のケースでは、すべてのコードをリファクタリングする必要があります(新しいクラスの実装には別の名前があります)。結果として、アノテーションは可能な限りインターフェース上にある必要があります。さらに、JDKプロキシはこれに非常に適しています。CGlibプロキシとは異なり、ランタイムタイプは事前にわかっているため、アプリケーションの起動時に作成およびインスタンス化されます。
簡単に言えば:
@ Serviceはserviceレイヤーのステレオタイプ注釈です。
@ Repositoryはpersispertenceレイヤーのステレオタイプ注釈です。
@ Componentはgenericステレオタイプアノテーションで、アプリケーションコンテキストでオブジェクトのインスタンスを作成するようSpringに指示するために使用されます。インスタンスに任意の名前を定義することができます。デフォルトはキャメルケースとしてのクラス名です。