Spring AOP架构的核心是建立在代理上的。
Spring AOP代理只支持一种连接点----方法调用。其功能是AOP规范的一个子集,但足够用了。
Spring代理有两种实现方式:JDK动态代理和CGLIB代理。CGLIB的代理性能要比JDK动态代理的性能好很多,不过开发人员不用需要关注这些,Spring自动会判断使用何种代理,并且默认Spring会选择使用CGLIB的代理,在此不做深入讨论。
Spring AOP代理是通过ProxyFactory类来获取代理对象的。最简单的过程是:
1、创建代理工厂:new一个ProxyFactory实例。
2、给代理工厂加入通知者:ProxyFactory.addAdvisor(),通知者构建方式很多。
3、将目标加入工厂:ProxyFactory.setTarget()设置要代理的对象。
4、获取目标的代理实例:ProxyFactory.getProxy(),通过代理实例来执行被代理的也无法方法。
在Spring AOP中,有两种方法将一个通知加入到代理中去。一是直接使用addAdvice()方法,二是使用addAdvice()和Advisor(通知者)类。前者在ProxyFactory中会委派给addAdvisor(),加入的是DefaultPointcutAdvisor。
Spring支持五类通知,这些通知都实现了Advice接口:
org.springframework.aop.AfterReturningAdvice
org.springframework.aop.IntroductionInterceptor
org.springframework.aop.MethodBeforeAdvice
org.aopalliance.intercept.MethodInterceptor
org.springframework.aop.ThrowsAdvice
在实际中,只需要实现以上五个标准接口即可,另外这些接口都是AOP联盟定义的标准接口。
下面通过实现MethodBeforeAdvice接口改写“Spring AOP 本质(1) ”中的例子,其他的不用改变,只需要将测试类实现MethodBeforeAdvice接口即可。
下面是改写后的代码:
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
public class SimpleBeforeAdvice implements MethodBeforeAdvice {
public static void main(String[] args) {
//被代理对象
MessageWriter target = new MessageWriter();
//代理工厂
ProxyFactory pf = new ProxyFactory();
//给工厂添加通知(者),实际上ProxyFactory在后台加入的是一个DefaultPointcutAdvisor
pf.addAdvice( new SimpleBeforeAdvice());
//将目标加入代理工厂
pf.setTarget(target);
//从工厂获取代理实例(产品)
MessageWriter proxy = (MessageWriter) pf.getProxy();
//从代理实例上调用业务方法
proxy.writeMessage();
}
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println( "Before method: " + method.getName());
}
}
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
public class SimpleBeforeAdvice implements MethodBeforeAdvice {
public static void main(String[] args) {
//被代理对象
MessageWriter target = new MessageWriter();
//代理工厂
ProxyFactory pf = new ProxyFactory();
//给工厂添加通知(者),实际上ProxyFactory在后台加入的是一个DefaultPointcutAdvisor
pf.addAdvice( new SimpleBeforeAdvice());
//将目标加入代理工厂
pf.setTarget(target);
//从工厂获取代理实例(产品)
MessageWriter proxy = (MessageWriter) pf.getProxy();
//从代理实例上调用业务方法
proxy.writeMessage();
}
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println( "Before method: " + method.getName());
}
}
运行结果:
- Using JDK 1.4 collections
Before method: writeMessage
World
Process finished with exit code 0
Before method: writeMessage
World
Process finished with exit code 0
本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/75134,如需转载请自行联系原作者