若想要在例外發生時被通知作某些事,您可以使用Throws Advice,在Spring中想要實作Throws Advice,必須實作org.springframework.aop.ThrowsAdvice介面,然而這個介面並沒有定義任何的方法,它只是一個標籤(tag),您可以在當中定義任意的方法名稱,只要它是以下的形式:
代碼:
methodName([Method], [args], [target], subclassOfThrowable);
Method、args與target都是可以省略的,方法中一定要的是subclassOfThrowable,在例外發生時,會檢驗所設定的Throws Advice中是否有符合例外類型的方法,如果有的話就通知它執行,注意我們只能通知方法,並傳入例外物件,我們並不能在Throws Advice中將例外處理掉,例外處理仍舊是應用程式本身所要負責的。
來看個Throws Advice的實際例子,首先定義IHello介面:
代碼:
package onlyfun.caterpillar;
public interface IHello {
public void hello(String name) throws Exception;
public void morning(String name) throws Exception;
}
實作IHello介面的是HelloSpeaker:
代碼:
package onlyfun.caterpillar;
public class HelloSpeaker implements IHello {
public void hello(String name) {
System.out.println("Hello, " + name);
}
public void morning(String name) throws Exception {
System.out.println("Morning, " + name);
throw new Exception("exception happened!");
}
}
其中我們故意在morning()中丟出例外,以測試Throws Advice的運作,我們的Throws Advice編寫如下:
代碼:
package onlyfun.caterpillar;
import java.lang.reflect.*;
import java.util.logging.*;
import org.springframework.aop.ThrowsAdvice;
public class CustomExceptionAdvice implements ThrowsAdvice {
private Logger logger = Logger.getLogger(this.getClass().getName());
public void afterThrowing(Method method,
Object[] args,
Object target,
Throwable subclass) {
logger.log(Level.INFO,
"Logging that a " +
subclass +
"Exception was thrown in " + method);
}
}
我們的Throws Advice作的只是將例外發生時的相關資訊記錄下來,它並不處理例外,例外處理還是主程式要作的:
代碼:
package onlyfun.caterpillar;
import org.springframework.context.*;
import org.springframework.context.support.*;
public class SpringTest {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("bean.xml");
IHello helloProxy = (IHello) context.getBean("helloProxy");
try {
helloProxy.hello("Justin");
helloProxy.morning("momor");
}
catch(Exception e) {
}
}
}
當然,我們必須設定bean定義檔:
代碼:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "- "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="customExceptionAdvice" class="onlyfun.caterpillar.CustomExceptionAdvice"/>
<bean id="helloSpeaker" class="onlyfun.caterpillar.HelloSpeaker"/>
<bean id="helloProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>onlyfun.caterpillar.IHello</value>
</property>
<property name="target">
<ref bean="helloSpeaker"/>
</property>
<property name="interceptorNames">
<list>
<value>customExceptionAdvice</value>
</list>
</property>
</bean>
</beans>
程式執行時,呼叫hello()時是正常執行完畢的,然而呼叫morning()方法會丟出例外,Throws Advice會被通知,並記錄例外發生資訊:
代碼:
Hello, Justin
Morning, momor
2004/11/30 上午 11:05:30 org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor getExceptionHandler
資訊: Trying to find handler for exception of class java.lang.Exception
2004/11/30 上午 11:05:30 org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor getExceptionHandler
資訊: Looking at superclass class java.lang.Exception
2004/11/30 上午 11:05:30 onlyfun.caterpillar.CustomExceptionAdvice afterThrowing
資訊: Logging that a java.lang.Exception: exception happened!Exception was thrown in public abstract void onlyfun.caterpillar.IHello.morning(java.lang.String) throws java.lang.Exception