Spring源码分析之三级缓存是如何实现AOP代理问题

在上一篇文章中给大家分享了一下循环依赖的问题Spring源码分析之循环依赖,接下来就为大家分析一下三级缓存的存在是如何管理AOP(动态代理)的问题。

//这边不去执行 lambada表达式 只有调用getobject 的时候才会执行
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

 在doCreateBean()方法中有一个addSingletonFactory的方法,此方法是通过匿名内部类的方式将lambada表达式作为参数传入进去,这也是我们三级缓存解决循环依赖和AOP代理的关键。

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

在这个方法中exposedObject作为我们的当前的一个beanName进行了判断,如果我们不需要AOP生成代理对象增强这个bean,那么会直接return,而当我们的配置文件中存在AOP的配置的时候,会进入if条件中执行代理的方法,例如:

<bean id="logger" class="com.xianjiaochaorou.demo"></bean>

	<aop:config>
		<aop:aspect id="logger" ref="logger">
			<aop:poincut expression="execution(* com.xianjiaochaorou.circle.*.*(..))" id="method"
			<aop:before method="recordBefore" pointcut-ref="method"/>
			<aop:before method="recordAfter" pointcut-ref="method"/>
		</aop:aspect>
	</aop:config>
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);

 执行此方法之后会重新返回一个新的对象(代理对象)存入三级缓存中。

思考:为什么三级缓存可以解决这个问题? 为什么要使用一个匿名内部类的方式去实现?

首先我们应该知道,当一个对象需要被代理的情况下,这个时候在整个的创建过程中是包含两个对象的,一个就是普通的bean对象另一个是代理生成的对象,而在bean对象在创建的过程中默认是单例,所以一个beanName是不可以对应两个对象的,这个时候就需要进行判断,看是否当前的这个benaName是否需要被代理,如果需要则依据上文返回代理之后的对象,如果不需要则直接返回普通的bean对象。 为什么要使用匿名内部的类的方式呢?答案是因为我们并不知道什么时候需要代理对象什么时候需要普通对象,如果出现普通对象和代理对象混合的情况就会出现一个beanName存在两个对象的情况,所以干脆直接使用匿名内部类,也就是每当我们进行返回的时候都默认调用进行判断,这样在需要的时候就可以直接对普通对象进行覆盖,保证全局唯一!!!

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香蕉炒肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值