本例子Spring 實現攔截器
依賴的jar包有 aopalliance.jar cglib-full-2.0.2.jar commons-logging.jar spring.jar
Spring的AOP聲明式事務管理。
1. 幾個重要的概念
PointCut:一組JointPoint。在Spring中我們可以通過一些正則表達式定義那些JointPoint組成了我們需要的一個PointCut,從而使我們的Advice可以被編制進來。
Introduction:Introduction可以我們在已經存在的類中在不修改這個類的情況下增加屬性和方法,從而增加其狀態和動作;
Target:滿足PointCut定義的條件的一個類,我們可以把Advice用於這個類。大多Spring的AOP是通過動態代理的機制實現的,這個Target就是那個被代理的對象;
Proxy:爲了將一個Advice應用到另外一個類中,比如實現Around
Advice,就是在一個方法執行前後加上其他的代碼,那麼實際的實現一定是先執行一段Advice的代碼,然後執行Target的那個方法,之後再執行
一段Advice的代碼,也就是客戶端執行某個類的時候,實際執行的是一個代理,由代理再把調用傳遞到那個Target中。
Weaving(編織):有了Target和Advice,在什麼時機將這兩個模塊編織在一起呢?可以選擇的方法包括編譯的時候(這樣我們需要一個特
殊的編譯器),裝載類的時候(這樣我們需要一個特殊的ClassLoader)和運行的時候(AOP容易可以動態的創建一個代理從而將調用由這個代理傳遞
到Target類中)。
2. Throws Advice
項目中有一個要求,對於某些處理流程如果在運行的時候拋出了一些異常,需要將這些異常的信息記錄下來,保存在數據庫或發郵件給開發人員。
按照上面概念的描述,我們應該主要注意三個概念:Target,Advice和Proxy。
配置文件
<project name="MyProject" default="compile" basedir="."> <property name="sourcedir" value="${basedir}/src"/> <property name="targetdir" value="${basedir}/build"/> <property name="librarydir" value="${basedir}/lib"/> <path id="libraries"> <fileset dir="${librarydir}"> <include name="*.jar"/> </fileset> </path> <target name="clean"> <delete dir="${targetdir}"/> <mkdir dir="${targetdir}"/> </target> <target name="compile" depends="copy-resources"> <javac srcdir="${sourcedir}" destdir="${targetdir}" classpathref="libraries"/> </target> <target name="copy-resources"> <copy todir="${targetdir}"> <fileset dir="${sourcedir}"> <exclude name="**/*.java"/> </fileset> </copy> </target> <target name="run" depends="clean, compile"> <java classname="SimpleThrowsAdvice" fork="true" classpathref="libraries"> <classpath path="${targetdir}"/> </java> </target> </project>
ErrorBean.java
public class ErrorBean {
public void errorProneMethod() throws Exception {
throw new Exception("Foo");
}
public void otherErrorProneMethod() throws IllegalArgumentException {
throw new IllegalArgumentException("Bar");
}
}
SimpleThrowsAdvic.java
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.framework.ProxyFactory;
public class SimpleThrowsAdvice implements ThrowsAdvice {
public static void main(String[] args) throws Exception {
ErrorBean errorBean = new ErrorBean();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(errorBean);
pf.addAdvice(new SimpleThrowsAdvice());
ErrorBean proxy = (ErrorBean) pf.getProxy();
try {
proxy.errorProneMethod();
} catch (Exception ignored) {
}
try {
proxy.otherErrorProneMethod();
} catch (Exception ignored) {
}
}
public void afterThrowing(Exception ex) throws Throwable {
System.out.println("***");
System.out.println("Generic Exception Capture");
System.out.println("Caught: " + ex.getClass().getName());
System.out.println("***\n");
}
public void afterThrowing(Method method, Object[] args, Object target,
IllegalArgumentException ex) throws Throwable {
System.out.println("***");
System.out.println("IllegalArgumentException Capture");
System.out.println("Caught: " + ex.getClass().getName());
System.out.println("Method: " + method.getName());
System.out.println("***\n");
}
}