- サンプルコードとしては「JavaRebelを試す」のものを使うが、ButtonをClickしたときのソースを以下のように修正する。
label.setText(Messages.getMessage());
- Messages Classは以下のようなカンジで。
public class Messages { public static String getMessage() { return "hoge"; } }
- この辺りで実行開始。もちろん、ButtonをClickすると「hoge」とか表示される。この動作自体はどぅでも良い。
- 次に、JavassistをDownloadしてくる。Mavenであればpom.xmlに以下の依存を追加する。
<dependency> <groupId>jboss</groupId> <artifactId>javassist</artifactId> <version>3.6.ga</version> </dependency>
- Javassistを使って既存のClassのバイトコードにAdviceを追加する処理を行うClassを作成し、実行する。ClassPoolから取得するClass名(package名)やwriteFile()する時のフォルダ名は適宜変更する。
public class Javassist01 { public static void main(String[] args) { try { javassist.ClassPool classPool = javassist.ClassPool.getDefault(); javassist.CtClass ctClass = classPool.get("shin1o.Messages"); javassist.CtMethod ctMethod = ctClass .getDeclaredMethod("getMessage"); ctMethod .insertBefore("System.out.println(\"getMessage() before\");"); ctClass.writeFile("target/classes"); System.out.println("weaved."); } catch (Exception ex) { ex.printStackTrace(); } } }
この例だとclassの出力先は「target/classes」になっているが、Mavenを使わずにEclipseだけなら「bin」かも、 - これを実行すると、既存のMessagesClassが書き換えられる(weave)。
- 実行中の画面でButtonをClickすると、「hoge」と表示されることは変わらないが、Eclipseの標準出力には以下のような表示がされているはず!
JavaRebel: Reloading class 'shin1o.Messages'. getMessage() before
JavassistでMessagesクラスのバイトコードに直接埋め込んだ、getMessage()直前の「System.out.println("getMessage() before");」がちゃんと実行されている、と。 - プログラムを走らせたままAOPできるって事ですーーー!便利でしょ!?
2007年12月9日日曜日
JaveRebelを試す その2(Javassistと組み合わせる)
昨晩のエントリの「JavaRebelを試す」でJavaRebelを使うことでClassのDynamicLoadができますねー便利ですねーと簡単に書いたけど、内容が薄すぎて何が便利かを語りきれていないのでさらに追加。
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿