为了账号安全,请及时绑定邮箱和手机立即绑定

Spring AOP源码解析

标签:
Java

以编程的方式使用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对象,此接口才是真正产生代理对象的接口,其实现类有两个:JdkDynamicAopProxy和ObjenesisCglibAopProxy,分别对应JDK动态代理实现和Cglib实现。ProxyFactory的父类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()方法屏蔽了如何选择以及选择哪种代理,对客户端而言这些都是透明的。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消