← Spring コース
38. 動的プロキシ
は、指定した(持つべきだけを書いた型)を実装するを、実行時に作る 標準の仕組みです。そのに対するインターフェースのメソッドの呼び出しは、toString、equals、hashCode と合わせて、という1つの関数に届きます。ハンドラの中で本物のメソッドを呼べば、その前後にログ出力などの処理を挟めます。呼び出す側のコードは変わりません。
包み役のクラスを手で書いても同じことはできますが、インターフェースごと、メソッドごとに書くことになります。なら1つのハンドラで済みます。ハンドラには呼ばれたメソッドの情報が渡るので、前のレッスンのと同じ道具で扱えます。 がこの仕組みをどう使っているかは、後のレッスンで扱います。
つまずきどころはです。下のコードで placeOrder の中から this.audit() を呼ぶと、ハンドラを通りません。ハンドラが取り次いだ先は本物のオブジェクトで、その中の this はプロキシではないからです。また対象はインターフェースに限られ、クラスを渡すとになります。作られるクラスの名前は仕様では未規定で、この実測では $Proxy0 でした。
点線の付いた語はタップすると説明が出ます。用語集を開く →
呼び出す側svc.placeOrder()
OrderService 型として呼ぶ
プロキシ実行時に作られたクラスのインスタンス
インターフェースのメソッドの呼び出しはここに届く
ハンドラ前後に処理を挟み、本物へ取り次ぐ
method.invoke(real, args)
本物の placeOrder()この中の this は本物
本物の audit()this.audit() は直接ここへ。ハンドラを通らない
- ・Javadoc は「The unqualified name of a proxy class is unspecified.」と書いています。$Proxy0 という名前は実測値で、インターフェースが public のときは jdk.proxy1.$Proxy0 になりました(JDK 25)
- ・自己呼び出しがハンドラを通らないことは Javadoc の規則ではなく、ハンドラが本物へ取り次ぐ、という書き方から出てくる結果です
- ・ハンドラに届くのはインターフェースのメソッドと toString・equals・hashCode です。getClass など、Object から受け継いだそれ以外のメソッドは届きません(Javadoc)
▶ サンプルコードを実行してみよう(自由に書き換えてOK)
Java
図やコードに出てくる用語(タップで説明)
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗