本例子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"); } }