NOTE(2020/09/03): この記事は2013年に書かれており、古い内容になっています。現在のGroovyの実装と異なる場合があります。
いつも、PHPのことを話している人と思っているだろう。
実は、現在の大半のお仕事は Groovy によって行われているのだよ。
ブログでは初の Groovy ネタです。1年ほど、Groovy を触っているのですが、
私のような PHPer でも (一応、Javaの経験は昔にある) すんなり触ることができる
素晴らしい言語です。
大体のことは、プログラミングGroovy で学べました。
良い本です。
今回は、Groovy の Interception についてメモです。
NOTE (2020/09/03): Groovyをホスティングしていた、Codehaus が2015年にサービス終了してしまったために、リンク切れとなっていました。現在のGroovyドキュメントに当該の記述が見つからなかったため、参考リンクとして以下を貼ります。
Internet Archive へのリンク
Interceptor のテストコード
API Doc (Interceptor)
Interception と言えば、Spring Framework なんかにある、特定のメソッドの
実行前と、実行後に何らかのロジックを仕込むアイツです。
PHP で言えば、BEAR.Sunday が、この機構を見事に持ってます。
AOP 的には、本質 (実際のロジック) でない横断的な感関心事 (実行時間計測・ロギング)
は、本質とは別に実装せよ。とのことらしいです。
というわけで、実際のコードを確認。
まずは、こんなコードを用意して、GroovyConsole あたりで実行してみましょう。
class Hello { def name Hello(def name) { this.name = name } void sayHello() { println "Hello, ${name}." } } def h = new Hello("bucyou") h.sayHello() // Hello, bucyou.この、クラスに対して、Interceptor を差し込みます。
class Hello { def name Hello(def name) { this.name = name } void sayHello() { println "Hello, ${name}." } } class MyInterceptor implements Interceptor { // 前処理 Object beforeInvoke(Object object, String methodName, Object[] argments) { println "beforeInvoke ${methodName}" null } // 自動的にメソッドを invoke する場合は true boolean doInvoke() { true } // 後処理 メソッド実行の結果を result で改変できる Object afterInvoke(Object object, String methodName, Object[] argments, Object result) { println "afterInvoke ${methodName}" result } } def proxy = ProxyMetaClass.getInstance(Hello); proxy.interceptor = new MyInterceptor(); // ここは interceptor による割り込みはない def h1 = new Hello("bucyou"); h1.sayHello(); // use を使った部分だけ interceptor により割り込み有り proxy.use { def h2 = new Hello("bucyou2"); h2.sayHello() // Hello, bucyou. }そうすると、出力結果としては
Hello, bucyou.
beforeInvoke ctor
afterInvoke ctor
beforeInvoke sayHello
beforeInvoke println
Hello, bucyou2.
afterInvoke println
afterInvoke sayHelloとなります。メソッド名で振り分けているわけではないので、コンストラクタや
println() でも、beforeInvoke, afterInvoke が走っています。
Advisor 的なものを作れば、Groovy 単体で、十分に機能する Interceptor
実装が出来るかもしれません。