标签:spingaop sping aop 实现原理 源码解析
以编程的方式使用spring提供的AOP功能,下面是一个简单的例子:package com.zws.spring.core.aop.springAop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;
public class SpringProxyClient {
public static void main(String[] args) {
ProxyFactory proxy = new ProxyFactory(new SpringPojo());
proxy.addAdvice(new PojoAdvice());
SpringPojo proxyPojo = (SpringPojo) proxy.getProxy();
proxyPojo.foo();
}
}
class SpringPojo {
public void foo() {
System.out.println("This is SpringPojo foo");
}
}
class PojoAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("This is bar");
}
}这段代码最重要的一个类是ProxyFactory,此类以及相关的类的类图如下:

如果想要使用AspectJ风格的AOP可以使用AspectJProxyFactory。在使用ProxyFactory生成代理对象的时候,当实例化ProxyFactory对象时就会收集代理目标对象的接口信息,源代码如下:
public ProxyFactory(Object target) {
setTarget(target);
setInterfaces(ClassUtils.getAllInterfaces(target));
}代理目标的接口信息存放在类AdvisedSupport的interfaces属性中,此属性是一个集合,如下:
private List<Class<?>> interfaces = new ArrayList<Class<?>>();
当然在实例化ProxyFactory对象之前Spring还会实例化一个更重要的对象:AopProxy对象,此接口才是真正产生代理对象的接口。父类ProxyCreatorSupport会保存一个AopProxyFactory类型的属性aopProxyFactory,如下:
private AopProxyFactory aopProxyFactory;
此属性会在ProxyCreatorSupport的无参构造函数中实例化,如下:
/**
* Create a new ProxyCreatorSupport instance.
*/
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}当调用ProxyFactory的getProxy()方法时首先会调用DefaultAopProxyFactory类的createAopProxy()方法产生一个AopProxy对象,此时就需要判断使用JDK的动态代理还是GCLIB的代理类产生代理对象,在条件允许的情况下Spring会首选JDK动态代理的方式,其判断逻辑为目标对象类型是接口或者其本身就已经是一个JDK动态代理生成的对象。如果不满足上面的条件就使用Cglib代理生成代理对象,其源码如下:
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}AopProxy对象生成后就可以直接调用其getProxy()方法产生代理对象了。AopProxyFactory接口的createAopProxy()方法屏蔽了如何选择以及选择哪种代理,对客户端而言这些都是透明的。
标签:spingaop sping aop 实现原理 源码解析
原文地址:http://blog.51cto.com/wenshengzhu/2113299