Spring Dataリポジトリは実際にどのように実装されていますか?質問する

Spring Dataリポジトリは実際にどのように実装されていますか?質問する

私はしばらくの間、プロジェクトで Spring Data JPA リポジトリを使用してきましたが、以下の点を知っています。

  • リポジトリ インターフェイスでは、次のようなメソッドを追加できますfindByCustomerNameAndPhone()(およびはドメイン オブジェクト内のフィールドであるcustomerNameと想定します)。phone
  • 次に、Spring は、実行時 (アプリケーションの実行中) に上記のリポジトリ インターフェース メソッドを実装することで実装を提供します。

私はこれがどのようにコード化されているかに興味があり、Spring JPA ソース コードと API を調べましたが、以下の質問に対する答えを見つけることができませんでした。

  1. リポジトリ実装クラスは実行時にどのように生成され、メソッドはどのように実装および注入されるのでしょうか?
  2. Spring Data JPA は、メソッドを実装して動的に挿入するために CGlib またはバイトコード操作ライブラリを使用しますか?

上記の質問についてご支援いただき、またサポートされているドキュメントも提供していただけますか?

ベストアンサー1

まず、コード生成は行われません。つまり、CGLib もバイトコード生成もまったく行われません。基本的なアプローチは、Spring のProxyFactoryAPI を使用してプログラム的に JDK プロキシ インスタンスを作成し、インターフェイスをサポートし、MethodInterceptorインスタンスへのすべての呼び出しをインターセプトして、メソッドを適切な場所にルーティングすることです。

  1. リポジトリがカスタム実装部分で初期化されている場合(参照ドキュメントのその部分詳細については、こちらをご覧ください。呼び出されたメソッドがそのクラスに実装されている場合、呼び出しはそこにルーティングされます。
  2. メソッドがクエリメソッドの場合(DefaultRepositoryInformationどのように決定されるかは、ストア固有のクエリ実行メカニズムが起動し、起動時にそのメソッドに対して実行されるように決定されたクエリを実行します。そのために、さまざまな場所で明示的に宣言されたクエリを識別しようとする解決メカニズムが用意されています(@Queryメソッドで、JPA の名前付きクエリを使用)。最終的にはメソッド名からのクエリ派生に戻ります。クエリメカニズムの検出については、JpaQueryLookupStrategyクエリ導出の解析ロジックについては、PartTree店舗固有の実際のクエリへの翻訳は、例えば以下で確認できます。JpaQueryCreator
  3. 上記のいずれにも当てはまらない場合、実行されるメソッドはストア固有のリポジ​​トリ基本クラスによって実装されたものでなければなりません(SimpleJpaRepository(JPA の場合)、呼び出しはそのインスタンスにルーティングされます。

そのルーティングロジックを実装するメソッドインターセプターはQueryExecutorMethodInterceptor、高レベルのルーティングロジックは、ここ

これらのプロキシの作成は、標準的なJavaベースのファクトリーパターン実装にカプセル化されています。高レベルのプロキシ作成は、RepositoryFactorySupportストア固有の実装では、必要なインフラストラクチャ コンポーネントが追加されるため、JPA の場合は、次のようなコードを記述するだけで済みます。

EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);

私が明示的にそのことを述べた理由は、そのコードの核心では、そもそも実行するために Spring コンテナを必要としないことが明らかになるはずだからです。クラスパス上のライブラリとして Spring が必要ですが (車輪の再発明は避けたいため)、一般的にコンテナに依存しません。

DIコンテナとの統合を容易にするために、もちろんSpring Java構成、XML名前空間との統合も構築しましたが、CDI 拡張これにより、Spring Data を単純な CDI シナリオで使用できるようになります。

おすすめ記事