-例外をトラップするAdvice

明日のPPTの用意で作ったAdvice第二弾です。例外をトラップするために、まじめに作ったAdvice。

package org.seasar.framework.aop.advices;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.seasar.framework.aop.AroundAdvice;
import org.seasar.framework.aop.Joinpoint;
public class ThrowHandleAdvice implements AroundAdvice {
  private Set handlers = new HashSet();
  public void addHandler(ThrowHandler handler) {
    handlers.add(handler);
  }
  private boolean fireThrowHandlers(Throwable t, 
    Joinpoint joinpoint) throws Throwable{
    boolean ret = false;
    for(Iterator it = handlers.iterator(); it.hasNext();) {
      ThrowHandler handler = (ThrowHandler)it.next();
      if(handler.handleThrowable(
        t, joinpoint.getTarget(), joinpoint.getMethod(), joinpoint.getArgs())) {
        ret = true;      
      }
    }
    return ret;
  }
  public Object invoke(Joinpoint joinpoint) throws Throwable {
    Object ret = null;
    try {
      ret = joinpoint.proceed();
    } catch(Throwable t) {
      if(!fireThrowHandlers(t, joinpoint)) {
        throw t;
      }
    }
    return ret;
  }
}

ハンドラはインターフェイスを実装します。

package org.seasar.framework.aop.advices;
import java.lang.reflect.Method;
public interface ThrowHandler {
  public boolean handleThrowable(
          Throwable t, Object target, Method method, Object[] arg);
}

サンプル設定は以下のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<components>
  <component name="runtimeExceptionHandler"
    class="tutorial.org.seasar.console.RuntimeExceptionHandler"/>
  <component name="crash" class="tutorial.org.seasar.console.CrashCar">
    <aspect>
      <component class="org.seasar.framework.aop.advices.ThrowHandleAdvice">
        <initMethod name="addHandler">
          <arg>runtimeExceptionHandler</arg>
        </initMethod>
      </component>
    </aspect>
  </component>
</components>

サンプル用のハンドラです。

package tutorial.org.seasar.console;
import java.lang.reflect.Method;
import org.seasar.framework.aop.advices.ThrowHandler;
public class RuntimeExceptionHandler implements ThrowHandler {
  public boolean handleThrowable(
        Throwable t, Object target, Method method, Object[] args) {
    if (t instanceof RuntimeException) {
      System.out.println("target:" + target.getClass().getName());
      System.out.println("method:" + method.getName());
      System.out.println("throwable:" + t.getMessage());
      return true;
    } else {
      return false;
    }
  }
}

サンプル用コンポーネントです。

package tutorial.org.seasar.console;
public class CrashCar implements Car {
  public void run() {
    throw new RuntimeException("crush!");
  }
}