まず第一に、進行中のコード生成はありません。つまり、CGLibもバイトコード生成もまったくありません。基本的なアプローチは、SpringのProxyFactory
APIを使用してプログラムでJDKプロキシインスタンスを作成し、インターフェースをバックアップMethodInterceptor
し、インスタンスへのすべての呼び出しをインターセプトし、メソッドを適切な場所にルーティングすることです。
- リポジトリがカスタム実装部分で初期化されており(詳細についてはリファレンスドキュメントのその部分を参照)、呼び出されたメソッドがそのクラスで実装されている場合、呼び出しはそこにルーティングされます。
- メソッドがクエリメソッドである場合(
DefaultRepositoryInformation
その決定方法については、「」を参照)、ストア固有のクエリ実行メカニズムが起動し、起動時にそのメソッドに対して実行すると決定されたクエリを実行します。そのため、さまざまな場所で明示的に宣言されたクエリ(@Query
メソッドでJPA名前付きクエリを使用)を識別しようとする解決メカニズムが導入され、最終的にメソッド名からのクエリ派生にフォールバックします。クエリメカニズムの検出については、を参照してくださいJpaQueryLookupStrategy
。クエリ派生の解析ロジックは、にありますPartTree
。実際のクエリへのストア固有の翻訳は、たとえばで確認できますJpaQueryCreator
。
- 上記のいずれも当てはまらない場合、実行されるメソッドは、ストア固有のリポジトリ基本クラス(
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シナリオで使用できます。
@Repository
最初にSpringが注釈付きインターフェースを発見する方法について詳しく説明していただけますか これを見るとRepositoryFactorySupport#getRepository()
、インターフェイスクラスをパラメーターとして取るので、別の場所で発見する必要があります。私は特に、注釈付きインターフェースを見つけ、そのインターフェースを実装するJDKプロキシBeanを自動生成する方法を見つけようとしています。これは、Spring-Dataと非常によく似ていますが、リポジトリに関連しないアプリケーション固有の目的のためです。