Seasar Conference〜Load-time weaveingで広がるAOPの可能性〜

S2Javelinでシーケンス図出すデモでやってることは?
1.S2JavelinのInterceptorを出したいトコに指定する。
2.S2Javelinがシングルトンじゃないと動かないので、シングルトンにする。
3.S2のAbstractInterceptor#getTargetClass()で落ちるので、そこも書き換える。


package demo;

import org.seasar.framework.util.TextUtil;

public class Sequence {
public static void main(String[] args) {
String text = TextUtil.readText("foo_bar.txt");
System.out.println(text);
}
}

// -javaagent:lib/kimu-aop-core-0.2.0-SNAPSHOT.jar -Djavelin.property=javelin/javelin.properties

で、TextUtilを動かす。


package jp.dodododo.aop.seasar;

import jp.dodododo.aop.annotation.Enhance;
import jp.dodododo.aop.interceptors.AbstractMethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;
import org.seasar.javelin.S2JavelinInterceptor;

@Enhance(false)
public class S2JavelinInterceptorProxy extends AbstractMethodInterceptor {

private static S2JavelinInterceptor theInstance = new S2JavelinInterceptor();

@Enhance(false)
public Object invoke(MethodInvocation invocation) throws Throwable {
return theInstance.invoke(invocation);
}

}

でシングルトン。


package jp.dodododo.aop.seasar;

import jp.dodododo.aop.annotation.Enhance;
import jp.dodododo.aop.interceptors.AbstractMethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;
import org.seasar.framework.aop.S2MethodInvocation;

@Enhance(false)
public class GetTargetClassInterceptor extends AbstractMethodInterceptor {

@Enhance(false)
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation invocation = (MethodInvocation) mi.getArguments()[0];
if (invocation instanceof S2MethodInvocation) {
S2MethodInvocation s2Invocation = (S2MethodInvocation) invocation;
return s2Invocation.getTargetClass();
}
return getTargetClass(invocation);
}

}

で、S2AOPの中を差し替え。





new jp.dodododo.aop.seasar.GetTargetClassInterceptor()




new jp.dodododo.aop.seasar.S2JavelinInterceptorProxy()



が、設定。


AOP Alliance的には、staticメソッドだったら、getThis()はnullを返すことになっててS2AOPの中で落ちるんだけど、S2AOPはS2前提なのでという話と、SpringとかいろんなAOPといろいろ組み合わせてつかうと、ターゲットの取り方かわってくるので、使うAOPの実装にあわせる必要が出てくるので、上のコードも変える必要が出たり出なかったり。
ちなみに、S2AOPのここ↓を差し替えている。


protected Class getTargetClass(MethodInvocation invocation) {
if (invocation instanceof S2MethodInvocation) {
return ((S2MethodInvocation) invocation).getTargetClass();
}
Class thisClass = invocation.getThis().getClass();
Class superClass = thisClass.getSuperclass();
if (superClass == Object.class) {
return thisClass.getInterfaces()[0];
}
return superClass;
}


感想ブログ
http://d.hatena.ne.jp/kimpo/20090316#1237207556
http://d.hatena.ne.jp/kuniku/20090316/1237176562