JavassistはJavaライブラリであり、アプリケーションのJavaバイトコードを操作する手段を提供します。
わかりましたが、なぜバイトコードを操作する必要があるのですか?
実際の例はありますか? javassistが使用した実際のアプリはありますか?
一般的なアプリケーションは、実行時にプロキシクラスを生成することです。つまり、実行時にすべてのメソッド呼び出しをインターセプトするサブクラスを作成します。例:
Hibernateは、プロキシを使用してエンティティのメソッド呼び出しをインターセプトし、遅延読み込みを実装します。つまり、最初にアクセスしたときにデータベースからオブジェクトをフェッチします。
Spring Frameworkプロキシを使用してAOPサポートを実装します これは、とりわけ宣言型トランザクションのサポートを強化します。また、プロキシを使用して適切なスコープを適用します。
[〜#〜] ejb [〜#〜]は、プロキシを使用して、コンテナ管理トランザクション、承認チェックを実装し、ユーザー定義のインターセプターを適用します。
[〜#〜] cdi [〜#〜]実装は、適切なスコープを確保するために、マネージドBeanもプロキシする必要があります。彼らもバイトコードエンジニアリングライブラリを使用しているのではないかと思います。
[〜#〜] i [〜#〜]最近、Javassistを使用して、すべてのメソッド呼び出しをインターセプトし、委任するだけで、メソッドの戻り値の透過キャッシュを実装しました。最初の呼び出しでスーパー実装に。
ご了承ください Java.lang.reflect.Proxy
は実行時にプロキシクラスを生成できますが、インターフェイスのみを実装でき、クラスを拡張することはできません。上記のすべてのユースケースでは、クラスのプロキシが必要です。
バイトコード操作は、特に特定のプロジェクトのソースコードがない場合に、便利で必要です。一部のプロジェクトのバイトコード(jarファイルなど)しか持っていないが、コードの動作を何らかの方法で変更したい場合は、バイトコード操作ライブラリがそのような場合に役立ちます。バイトコード操作の利点は、コードを再コンパイルする必要がなく、操作後に直接実行できることです。
私はバイトコード操作を使用してプログラム分析を行いました。ライブラリが与えられた場合、実行時にライブラリ内のどのメソッドが呼び出されたかを知りたいです。バイトコード操作を使用して、メソッドの先頭にSystem.out.println("method_name");
ステートメントを挿入できます。したがって、実行時に、呼び出されたメソッドが出力されます。
いくつかのバイトコード操作ライブラリは次のとおりです。
メリトンの答えを拡張し、実際の使用例を提供するには:
Hibernate-core(5.2.8.Final)はjavaassit(3.20.0-GA)を使用します:
https://mvnrepository.com/artifact/org.hibernate/hibernate-core/5.2.8.Final
ASMプロジェクトのユーザーページには、広く使用されている数十のJavaバイトコードの分析と操作にASMを使用するプロジェクトとフレームワークがリストされています。 http://asm.ow2.org/users.html