com.sun.proxy.$Proxyとは?
異なるフレームワーク(例えばEJB仕様を実装したフレームワークやJPAプロバイダなど)の深い部分でエラーが発生した場合、スタックトレースに com.sun.proxy.$Proxy
のようなクラスが含まれていることを見たことがあります。Proxyが何であるかは知っていますが、私はより技術的でよりJavaに特化した答えを探しています。
1.どんなものなのか? 2.どのように作られるのか? 3.JVMとどのような関係があるのか?JVMの実装に依存するのか?
52
2
1.プロキシは、実行時に作成されロードされるクラスです。これらのクラスには、ソースコードはありません。コードがないのに、どうやって何かをさせるのか、不思議に思っている方もいらっしゃると思います。その答えは、作成時に
InvocationHandler
を実装したオブジェクトを指定し、プロキシメソッドが呼び出されたときに呼び出されるメソッドを定義しているからです。2.呼び出しを使って作成します。
その論拠は
これについては、
Proxy
クラスのドキュメントを参照してください。3.バージョン1.3以降のJVMの実装は、必ずこれらをサポートする必要があります。これらは、実装固有の方法でJVMの内部データ構造に読み込まれますが、動作は保証されています。
どんなものですか?
特別なことはありません。一般的なJavaのクラスインスタンスと同じです。
しかし、これらのクラスは
java.lang.reflect.Proxy#newProxyInstance
によって作られたSynthetic Proxy Class
である。JVMとの関係は?JVMの実装に特化したものなのか?
1.3から導入された
http://docs.oracle.com/javase/1.3/docs/relnotes/features.html#reflection
Javaの一部であるため、各JVMはこれをサポートする必要があります。
どのように作成されるのでしょうか(Openjdk7ソース)。
要するに、JVMのASM技術(実行時にジャババイトコードを定義する)を使って作成されているのです。
同じ技術を使ったものがある。
java.lang.reflect.Proxy#newProxyInstance` を呼び出したらどうなるか?
getProxyClass0
を呼び出してClass<? を取得します。 1.たくさんのキャッシュや何かの後に、魔法のような
ProxyGenerator.generateProxyClass` を呼び出し、byte[]を返します。define class
を呼び出して、生成された$Proxy
クラス(見たことのあるクラス名)をロードする。 1.インスタンス化するだけですぐに使えるmagic sun.misc.ProxyGenerator の中で起こること。
インターフェースに含まれるすべてのメソッドを1つにまとめたクラス(バイトコード)を作成する。
各メソッドは、以下のような同じバイトコードでビルドされます。
1.呼び出し方法メス情報(生成時に保存)を取得する。
'の
invoke()` に情報を渡す。invocation ハンドラ
'のinvoke()
から戻り値を取得する。 1.ただ返すだけクラス(バイトコード)をバイト[]の形で表現する。
授業の描き方について
Javaのコードがバイトコードにコンパイルされていると考えて、実行時に以下のように実行します。
Talk is cheap show you the code
sun/misc/ProxyGenerator.java のコアメソッド。
generateClassFile
addProxyMethod
プロキシメソッドに関する全コード