码迷,mamicode.com
首页 > 编程语言 > 详细

Spring AOP源码解析

时间:2018-05-06 18:58:26      阅读:225      评论:0      收藏:0      [点我收藏+]

标签: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()方法屏蔽了如何选择以及选择哪种代理,对客户端而言这些都是透明的。

Spring AOP源码解析

标签:spingaop   sping   aop   实现原理   源码解析   

原文地址:http://blog.51cto.com/wenshengzhu/2113299

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!