Spring(十九):AOP代理——JdkDynamicAopProxy、填坑:AOP代理与上循环依赖

本文深入探讨了Spring AOP中的JdkDynamicAopProxy工作原理,包括如何解决内部调用无法被代理拦截的问题,以及在创建Bean时如何通过三级缓存解决循环依赖。

回顾

之前我们已经详细说明了Bean是如何被代理的,最终Bean会被解析成JdkDynamicAopProxy或者ObjenesisCglibAopProxy对象了,对应JDK代理和Cglib代理,下面就来仔细看看这两个对象吧

还是回到之前DefaultAopProxyFactory的createAopProxy

在这里插入图片描述
这里的config已经有了之前解析出来的增强器和拦截器了(一个总的数组集合)、还有一些Bean的信息

JdkDynamicAopProxy

先进来看看这个类
在这里插入图片描述
可以看到这个类实现了InvocationHandler,这下估计都懂怎么回事了吧。。。

先看一下它的构建方法

	public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
   
   
		Assert.notNull(config, "AdvisedSupport must not be null");
        //判断增强器和拦截器的数量
		if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
   
   
            //如果为0就抛出异常
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
        //注入配置
		this.advised = config;
        //看不懂。。。
		this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		//判断有没有定义的equals方法和hashCode方法
        findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
	}

可以看到,构造方法只是注入了一下属性,并且判断增强器和拦截器的数量而已,比较重要的是查找有有没有定义的equals方法和hashCode方法

JdkDynamicAopProxy就是一个JDK的proxy代理类,所以我们去关注它的invoke方法

源码如下,很长,一看就很复杂

@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
   
		Object oldProxy = null;
		boolean setProxyContext = false;
		//获取被增强的对象的Class
        //这里比较特殊,之前的动态代理,我们都是直接new一个进来的
        //那么此时被代理的对象都还没有被IOC容器创建完,要怎么获取实例呢?
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;
		
		try {
   
   
            
           	//前面我们是已经对于equals方法是经过搜索的,如果出现了重写
            //那就代表了定义过
            //判断当前执行的方法是不是equals方法,并且有没有定义过
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
   
   
				// The target does not implement the equals(Object) method itself.
                //如果没有重写equals方法,那就使用默认的equals方法
				return equals(args[0]);
			}
            //对hashCode方法进行同样处理
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
   
   
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
            //如果当前之心的方法的类型是DecoraingProxy.class
            //执行下面的逻辑
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
   
   
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
            //如果执行的方法是来自于接口的,并且方法属于的类还是一个Advised.class
            //证明了这是代理对象的代理对象(即被代理对象是一个代理对象,还实现了接口)
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
   
   
				// Service invocations on ProxyConfig with the proxy config...
                //执行invokeJoinpointUsingReflection
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值