質問: ### 質問内容 下記を前提と致します。 ・webアプリを対象としています ・コーティングの方法ではなく、各項目に対する認識や理解の部分についてお尋ねしております 1. インターフェースのメソッドについて JpaRepmsitoryなどのインターフェース(上位のインターフェース含む)に定義されたメソッド(find,save等)の処理内容は何処にあるのでしょうか? 今の私の理解度だと、JpaRepmsitoryを実装した具象クラスがどこかにあり、そのクラスに処理内容が定義されていると思っているのですがこの点は間違いないでしょうか? (インターフェースについて上記理解で間違い無いかの確証が欲しいです) 2. find()について find...By...()はインターフェース側にメソッド定義するだけで、条件指定の検索が行えますが、どうやってこれが実現されているのかさっぱりわかりません。 メソッド名から文字抽出して、処理に反映させるなんてことが出来るのでしょうか? 3. Pageについて ページネーションを実現する際に使用していますが、感覚としてListなどのコレクションにページ番号などのフィールドが定義されたようなものといった認識でも良いのでしょうか? また、画面の各ページリンクからControllerへ遷移する時、一緒にリクエストパラメータにページ番号を付けて送りますが、受取側のControllerに受け取る為の変数を用意していないのに、ページが正常に切り替わります。Page実装クラスが勝手に受け取っているのでしょうが、具体的にどの様に実現されているのでしょうか? 昨日からspringを業務で使う様になりましたが、初めて目にするものばかりで理解が追いついておりません。 初歩的な質問ばかりではありますが何卒宜しくお願い致します。 ### Pageについて(自己解決) ・Pageは、オブジェクトリスト(Listでは無い)のサブリストである。Listのget/addの様に1つの要素にアクセスする方法があるのかは分からないが、Iterableインターフェースを継承しているため、for-eachでアクセスは可能である。 ・RDBからPageを取得するイメージとして、まずJPAなどにより検索条件に合致した(もしくは全レコード)仮のリスト(ORM)を取得して、このリストから指定したページ情報分のPageを作成する? ### リクエストパラメータのページ情報について(Pageable) 結論として、コントローラの引数に指定していたPageableが勝手に取得してくれていた。PageableはPage関連のページ情報を受渡しするオブジェクトであり、実装クラスとしてPageRequestがある。 Pageableが取得してくれるリクエストパラメータは決まっており、 "page","size","sort"などがある。
回答: 1について ===== そのとおりです。 2について ===== Springの実装詳細を自分は知りません。が、Javaで何ができ得るかについてコメントしてみます。 Spring Data JPAには、Repositoryインターフェースに宣言されたメソッドを、その名前からクエリを生成して自動的に生成してくれる機能があるとのことです。実装の仕方は色々考えられますが例えばjava.lang.reflect.Proxyというクラスを利用すると次のようなことができます。 (1) 特定の(複数の)インターフェースとInvocationHandlerを指定してインスタンスが作れる。 (2) そのインスタンスは指定したインターフェースを実装(interface Xxx implements I1, I2, ... のように宣言したクラスXxxであるかのように)している。 (3) そのインスタンスに対してインターフェースで規定されたメソッドを呼び出すことができる (4) そのメソッドを呼び出すとProxyの内部機構を介して(1)で指定したInvocationHandlerインスタンスのinvokeメソッドの呼び出しに(自動的に)置き換わってくれる。 InvocationHandler#invokeメソッドへはProxyインスタンスや呼び出されたメソッドを表すメタ情報(java.lang.reflect.Method)や渡された引数が渡されます。よってInvokeを実装するプログラマーは findByLastnameAndFirstname なんていう名前のメソッドが呼び出されたときメソッドの名前をjava.lang.reflect.Methodから取り出して えーと最初が"findBy"でその後に"Lastname"と"And"と"Firstname"が続いているからDBの検索条件のQUERYを「... where e.lastname = ?1 and e.firstname = ?2」という具合にして、このメソッドに渡された2つの引数をQueryの引数として指定する なんてことが実装できます。このあたり(InvocationHandler)はアプリケーション開発者が作る必要はなくSpringフレームワークのランタイムとして実装されていると思います。 ちなみにProxyを利用して実装しているなら、多分Invokeが呼び出されたときに一々メソッド名を解析するのではないでしょう。あらかじめインターフェース上にあるメソッド一覧を調べて各メソッドに必要なQueryのテンプレートなりを準備した上でInvokeされたら最小限の手間でqueryを生成(発行?)するようになっているのだろうと想像します。 3について、自分はSpringについて名前ぐらいしか知らないので他の方の回答に期待します。