Spring 的异常通知是在方法抛出异常之后将通知织入。需要注意的是异常通知只是当方法抛出异常时对抛出异常的情况进行操作,它不会捕获原方法抛出的异常,但是你可以通过异常通知抛出新的异常,我觉得这并不是一个好的主意。
Spring 提供了ThrowAdvice 接口来实现异常通知。ThrowAdvice 接口只是一个标示接口,它没有任何的方法,但是在使用时我们需要实现afterThrowing 方法来实现通知的具体内容。通过异常参数类型的定义,通知织入相的对应的异常之中,即当afterThrowing 的参数指定为NumberFormatException 异常时,当原方法抛出了该异常,通知被自动的执行。例子如下:
1)异常通知
public class Throw implements ThrowsAdvice
{
public void afterThrowing(
Method method,
Object[] args,
Object target,
RuntimeException throwable) {
System.out.println("Throw.afterThrowing()");
System.out.println("method name: " + method.getName());
Type[] type = method.getGenericParameterTypes();
for(int i = 0; i < type.length; i++) {
System.out.println(type[i].toString() + ": " + args[i]);
}
System.out.println("target: " + target.toString());
System.out.println("throw: " + throwable.getClass().getName());
throw new NumberFormatException();
}
}
2)目标对象
public class Target implements Advice
{
public String test(int i, String s, float f) {
System.out.println("Target.test()");
System.out.println("target: " + this);
StringBuffer buf = new StringBuffer();
buf.append( "i = " + i);
buf.append( ", s = \"" + s + "\"");
buf.append( ", f = " + f);
throw new NullPointerException();
}
}
3)接口定义
public interface Advice
{
String test(int i, String s, float f);
}
4)配置文件
<beans> <bean id="throw" class="spring.Throw"/> <bean id="aop3" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="spring.Advice" /> <property name="interceptorNames"> <list> <value>throw</value> </list> </property> <property name="target"> <bean class="spring.Target" /> </property> </bean> </beans>