ひがやすを技術ブログ

電通国際情報サービスのプログラマ

ThrowsInterceptor


使えないSpringのThrowsAdviceにかわりに

S2のThrowsInterceptorを使えば、Springでもきちんと例外を
AOPで扱えるように(たぶん)なります。
#例外処理をS2用からSpring用に変えてます。


public abstract class ThrowsInterceptor implements MethodInterceptor {

public static final String METHOD_NAME = "handleThrowable";
private Map methods_ = new HashMap();

public ThrowsInterceptor() {
Method[] methods = getClass().getMethods();
for (int i = 0; i < methods.length; ++i) {
Method m = methods[i];
if (isHandleThrowable(m)) {
methods_.put(m.getParameterTypes()[0], m);
}
}
if (methods_.size() == 0) {
throw new AopConfigException(
"At least one handler method must be found in class " +
getClass());
}
}

private boolean isHandleThrowable(Method method) {
return METHOD_NAME.equals(method.getName())
&& method.getParameterTypes().length == 2
&& Throwable.class.isAssignableFrom(
method.getParameterTypes()[0])
&& MethodInvocation.class.isAssignableFrom(
method.getParameterTypes()[1]);
}

public Object invoke(MethodInvocation invocation)
throws Throwable {
try {
return invocation.proceed();
} catch (Throwable t) {
Method method = getMethod(t);
if (method != null) {
try {
return method.invoke(this, new Object[] {
t, invocation });
} catch (InvocationTargetException ite) {
throw ite.getTargetException();
}
}
throw t;
}
}

private Method getMethod(Throwable t) {
Class clazz = t.getClass();
Method method = (Method) methods_.get(clazz);
while (method == null && !clazz.equals(Throwable.class)) {
clazz = clazz.getSuperclass();
method = (Method) methods_.get(clazz);
}
return method;
}
}

ThrowsInterceptorを継承して、
Object handlerThrowable(Throwable, MethodInvocation)
を実装すればOK。
これがもしうまくいくなら、S2AOPとSpringAOPの互換性はかなり
高いことが証明されると思います。
試してみてもらえるとうれしいです。 -> id:koichikさん