AspectP開発中
PHPでAOPしてみた - localdiskで予告したとおり、本格的なAOPライブラリを現在開発中です。
名前はJavaのAOPライブラリ「AspectJ」をもじって「AspectP」に決めました。Rubyに「AspectR」というのがあるようなので、これでよいかな…と思ってたらPythonのAOP実装でAspectPというのがあるっぽい。
…まぁあまりメジャーなライブラリではないようなので気にしないようにします。ごめんなさい。以後気をつけます。
気を取り直して使い方などを説明しようと思います。
ポイントカットの方法
ポイントカットはコメントアノテーションで行うようにします。
<?php /** * @Aspect('intercepter' => 'LoggerIntercepter') * こう書くとexecuteメソッドにLoggerIntercepterが適用されます */ public function execute(){ }
最初のバージョンはコメントアノテーションはメソッドのみ有効な形でリリースしようかと思います。その後は、コンストラクタにAOPが出来たり、クラスにコメントアノテーションを書いて正規表現でポイントカットできるようにする予定です。こんな感じで。
<?php /** * @Aspect('intercepter' => 'LoggerIntercepter', 'pointcut' => '*Action') * こう書くとHogeControllerの「Action」終わるメソッドにLoggerIntercepterが適用されます */ public class HogeController { }
このへんはS2.PHP5に影響されてます。あんまり話題にのぼりませんがS2.PHP5はすごいですよ。今リリースされているRCはPHP5.3に対応していて名前空間をバリバリ使っているので勉強になります。
Intercepter
インターセプターは4種類用意します。
- BeforeAdvice
- Joinpointの前に呼び出されます。BeforeAdviceを実装したIntercepterはbeforeメソッドを実装しなければなりません。
- AfterAdvice
- Joinpointの後に呼び出されます。AfterAdviceを実装したIntercepterはafterメソッドを実装しなければなりません。
- AroundAdvice
- Joinpointの前後に呼び出されます。BeforeAdviceを実装したIntercepterはbefore, afterメソッドを実装しなければなりません。
- ThrowAdvice
- 例外が発生した時に呼び出されます。ThrowAdviceを実装したIntercepterはthrowingメソッドを実装しなければなりません。
ここらへんの発想はSpringから頂きました。Intercepterは上記4つのアドバイスを実装する形になります。例えばLogerIntercpeterがAroundAdviceを実装している場合、適用したメソッドの前後でログが出力される、という感じになります。
設定ファイルでよるAOP
アノテーションを使用するとコードを見ると適用されているAOPがわかるので、気に入っているのですがクラスよりも大きなスコープでAOPを適用したい場合が不便になります。たとえば管理者用ディレクトリadmin配下のクラス全てにログイン用のIntercepterを適用したい場合とか。そんな時のために設定ファイルでもAOPを適用できるようにしたいと思います。iniかxmlかyamlがファイル形式は決めていませんが…。
やろうかどうしようか迷っていること
まとめ
基本的な仕様は固まってますが、どこまでやるかというのはまだ決めてません。なにかご意見・ご要望等ありましたらコメント欄にお願い致します。