かつのりの日記2

わんくまでは珍しいJavaを中心とした日記です

目次

Blog 利用状況

書庫

日記カテゴリ

いろいろリンク

AOPのサポートを入れてみた

あんまり難しいAOPではなく単純なダイナミックAOPの機能を作成中のDIコンテナに追加しました。過去にDIコンテナを作ったときに、ある程度使っていたAOPライブラリを外部化していたのですが、それを組み込むことにしました。

サポートしている条件としては、

  • インターフェイス
  • 抽象クラス
  • 非finalの具象クラス
  • 非finalメソッド
  • 非brigedメソッド
  • 非staticメソッド

というところです。staticメソッドやコンストラクタ、フィールドアクセス等は対象外にしています。

インターフェイスだけならjava.lang.reflect.Proxyだけでもいけるのですが、微妙に不都合もあるので全て自前実装です。それでもダイナミックAOPの実装はJavassist辺りのバイトコードライブラリに慣れていると比較的簡単です。

例えば具象クラスにアスペクトを織り込むのであれば、動的に継承したクラスを作成して、アスペクトの織り込む対象のメソッドのみを動的にオーバーライドします。自分の場合はポイントカットを動的にできるように、全てのメソッドに対してオーバーライドを行うようにしていますが、この辺は好みの問題でしょう。

インタセプタの類は全てAOP Allianceにも準拠しています。これならSpringやSeasar2用に作られたインタセプタも実行できます。AOPモジュールが元々クラスローダを変更できない作りになっているので、これから修正しなくては。

投稿日時 : 2007年9月9日 22:07

Feedback

# re: AOPのサポートを入れてみた 2007/09/10 9:22 黒龍

AOP Alianceなんてのがあったんですね。勉強になります。

# re: AOPのサポートを入れてみた 2007/09/10 9:59 かつのり

AOP自体には規格ってものがないので、
こういうデファクトスタンダードを意識するのって重要なんですよね。

# re: AOPのサポートを入れてみた 2007/09/10 11:14 凪瀬

Javassistは触ったことないんですよね。
かつのりさんの話を聞いていると夢広がるAPIのように思えてくる…

# re: AOPのサポートを入れてみた 2007/09/10 12:17 かつのり

Javassistはcglib+asm見たいな感じですね。
cglibは高レベルAPIでasmは低レベルAPIで、
これを最初からもっているのがJavassistって感じです。

そこまで夢広がるAPIでもないですが、テクニックは必要です。
クラスファイルのバイナリを頭で処理できる才能があれば、
Javassistがなくてもどうにかなるのですがwww

まぁ何と言うか、単純に言うと最終的にはバイト列を、
クラスローダに食わせる為のフレームワークですね。

# re: AOPのサポートを入れてみた 2007/09/10 14:38 凪瀬

私、Javaのバイトコードってうまく読めないんですよ…
レジスタマシンのVMは脳内搭載してるんですが、
スタックマシンのVMは非搭載なんでインタープリタ並みの解析時間がかかってしまいます。

CA FE BA BE からなる呪文を書いてHello worldしてみたいところですが…。

# re: AOPのサポートを入れてみた 2007/09/10 14:49 かつのり

CGLibとかJavassistはバイトコードの知識が不要ですよ。
自分はクラスファイル内の構造はある程度理解していますが、
バイトコードは多少読める程度。
(EclipseのASMプラグインを入れるとメソッド単位で見れますよ。)

Javassistにいたっては文字列で書いたメソッド内のコードを元に、
新しいメソッドを作れるので、実は簡単なんですね。
SunのJavacと同じバイト列を生成しないと、
HotSpotによる最適化がされないので、
直接バイトコードをいじるっていうニーズは少ないと思います。

# re: AOPのサポートを入れてみた 2007/09/10 16:29 凪瀬

> 直接バイトコードをいじるっていうニーズは少ないと思います。

JavaVM上で動くJavaではない言語を作るときぐらいですかねぇ。

タイトル
名前
Url
コメント