[解決済み] Spring Dataのリポジトリは実際にどのように実装されているのでしょうか?
質問
私は以前からプロジェクトでSpring Data JPAリポジトリを使っており、以下の点を知っています。
-
リポジトリインターフェースに、以下のようなメソッドを追加することができます。
findByCustomerNameAndPhone()
(仮にcustomerName
とphone
はドメインオブジェクトのフィールドです)。 - そして、Springは実行時(アプリケーション実行時)に上記のリポジトリインターフェースのメソッドを実装することで、実装を提供します。
私はこれがどのようにコーディングされたかに興味があり、Spring JPAのソースコードとAPIを見ましたが、以下の質問に対する回答は見つかりませんでした。
- リポジトリ実装クラスはどのように実行時に生成され、メソッドは実装され、注入されるのですか?
- Spring Data JPAでは、CGlibやバイトコード操作ライブラリを使ってメソッドを実装し、動的にインジェクトしているのでしょうか?
上記のクエリについて、サポートされているドキュメントを提供していただけませんか?
どのように解決するのですか?
まず、コード生成は行われません。つまり、CGLibもバイトコードも全く生成されないということです。基本的なアプローチは、JDKプロキシのインスタンスをプログラム的に作成することで、Springの
ProxyFactory
APIを使ってJDKプロキシインスタンスをプログラム的に作成し、インターフェイスをバックアップすることです。
MethodInterceptor
はインスタンスへのすべての呼び出しをインターセプトし、 メソッドを適切な場所にルーティングします。
- リポジトリがカスタム実装部で初期化されている場合 ( リファレンスドキュメントのその部分 を参照)、呼び出されたメソッドがそのクラスで実装されている場合、呼び出しはそこにルーティングされます。
-
メソッドがクエリメソッドである場合 (
DefaultRepositoryInformation
を参照)、ストア固有のクエリ実行メカニズムが起動し、 起動時にそのメソッドに対して実行されることが決定されたクエリを実行します。そのために、様々な場所で明示的に宣言されたクエリを識別しようとする解決メカニズムがあります (@Query
を使用)、最終的にはメソッド名からクエリを派生させることになります。クエリメカニズムの検出についてはJpaQueryLookupStrategy
. クエリ導出のためのパースロジックはPartTree
. 店舗固有の実際のクエリへの変換は、例えば次のようになります。JpaQueryCreator
. -
上記のいずれにも当てはまらない場合、実行されるメソッドは、店舗固有のリポジトリベースクラスによって実装されたものでなければなりません (
SimpleJpaRepository
で実装されたものでなければならず、呼び出しはそのインスタンスにルーティングされます。
そのルーティングロジックを実装したメソッドインターセプターは
QueryExecutorMethodInterceptor
であり、上位のルーティングロジックは
ここに
.
これらのプロキシの作成は、標準的なJavaベースのFactoryパターンの実装にカプセル化されています。高レベルのプロキシ生成は、以下のサイトで見ることができます。
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シナリオで使用できるようにしました。
関連
-
[解決済み】Spring Data Maven Buildsの「プラグインの実行はライフサイクル構成でカバーされていません」を解決する方法
-
[解決済み] Spring Data JPAにおけるCrudRepositoryとJpaRepositoryのインターフェースの違いは何ですか?
-
[解決済み] Spring boot - マネージドタイプではありません。
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
JSPで「リストが型解決できない!」の解決方法
-
[解決済み] Spring Bootアプリケーションにポートを設定する方法
-
[解決済み] Java 8のインターフェイスメソッドで "final "が使えないのはなぜですか?
-
[解決済み] Spring Data JPAにカスタムメソッドを追加する方法
-
[解決済み] Spring Dataのリポジトリをテストするには?
-
[解決済み】PHPで適切なリポジトリパターンを設計するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スタイルが読み込まれず、ブラウザのコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
springboot project MIMEタイプ text/htmlで転送された静的ファイルを読み込む。
-
Java Exceptionが発生しました エラー解決
-
IllegalArgumentException この例外を解決する方法
-
SpringBootApplication を型解決できない。
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
java.lang.NoClassDefFoundError: org.apache.jasper.el.ELContextImpl クラスを初期化できませんでした。
-
Exception: java.util.NoSuchElementException: 行が見つかりません
-
javax.net.ssl.SSLException: 読み取りエラー: ssl=0xdeae5100: システムコール中の I/O エラー、接続 res
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について