私はしばらくの間、私のプロジェクトでSpring Data JPAリポジトリを使用してきましたが、次の点を知っています。
findByCustomerNameAndPhone()
などのメソッドを追加できます(customerName
およびphone
がドメインオブジェクトのフィールドであると想定)。私はこれがどのようにコーディングされているかに興味があり、Spring JPAのソースコードとAPIを見ましたが、以下の質問に対する答えを見つけることができませんでした:
上記のクエリを支援し、サポートされているドキュメントを提供してください。
まず第一に、進行中のコード生成はありません。つまり、CGLib、バイトコード生成はまったくありません。基本的なアプローチは、SpringのProxyFactory
APIを使用してプログラムでJDKプロキシインスタンスを作成し、MethodInterceptor
がインスタンスへのすべての呼び出しをインターセプトし、メソッドを適切な場所にルーティングすることです。
DefaultRepositoryInformation
を参照)、ストア固有のクエリ実行メカニズムが起動し、決定されたクエリを実行します起動時にそのメソッドに対して実行されます。そのため、さまざまな場所で明示的に宣言されたクエリ(メソッドで@Query
を使用、JPA名前付きクエリを使用)を最終的にメソッド名からのクエリ派生にフォールバックする解決メカニズムが用意されています。クエリメカニズムの検出については、 JpaQueryLookupStrategy
を参照してください。クエリ派生の解析ロジックは、 PartTree
にあります。実際のクエリへのストア固有の翻訳は、たとえばin JpaQueryCreator
.SimpleJpaRepository
)によって実装されるメソッドである必要があります。そのインスタンスにルーティングされます。そのルーティングロジックを実装するメソッドインターセプターはQueryExecutorMethodInterceptor
であり、高レベルのルーティングロジックは here にあります。
これらのプロキシの作成は、標準のJavaベースのFactoryパターン実装にカプセル化されます。高レベルのプロキシ作成は RepositoryFactorySupport
にあります。次に、ストア固有の実装により必要なインフラストラクチャコンポーネントが追加されるため、JPAの場合は次のようなコードを記述できます。
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
私が明示的に言及する理由は、そのコードの中で、最初に実行するためにSpringコンテナを必要とするコードはないことを明確にする必要があるからです。クラスパス上のライブラリとしてSpringが必要です(ホイールを再発明しない方が望ましいため)が、一般的にはコンテナに依存しません。
DIコンテナーとの統合を容易にするために、もちろんXMLネームスペースであるSpring Java構成との統合を構築しましたが、 CDI拡張機能 。これにより、Spring Dataを単純なCDIシナリオで使用できます。