Spring源码学习笔记(个人零碎篇)

Spring源码学习笔记

AOP

面向切面横向编程
AOP所用到的代理模式有jdk代理(java动态代理),CGLIB代理,Spring是没有默认使用哪个代理的,取决于代理对象是否为接口,为接口则使用jdk代理,否则则是CGLIB代理。
原生对象在什么时候被代理?
在bean初始化到时候就已经被代理了。
spring有7个后置处理器,在第4个的时候开始处理。
DefaultAopProxyFactory.java中选择代理模式。
抛出一个问题:java动态代理和CGLIB代理的底层实现?
反射
深入探讨:
为什么java动态代理必须是接口???
因为java是单继承多实现的,因为代理的对象已经默认集成了Proxy对象,所以只能实现接口。
代理后生成的字节码反编译
.java文件生成.class字节码文件后内容转变为jvm运行的指令,拿到它的字节码,就可以在前后增加一些指令实现代理。java提供了Proxy.java,其中generatorProxyClass方法可以修改生成字节码

循环依赖

在这里插入图片描述
a依赖b,b依赖a。
这边需要了解Bean的生命周期。
概念:
第一级缓存:单例池(singletonObjects)
Map<beanName: 单例对象> ConcurentHashMap

单例池中的对象为代理对象。代理对象的内部实际包裹了原始对象。
如何解决:
第二级缓存(earlySingletonObjects)
实例化的原始对象存入缓存(一个Map),但是这边的原始对象是没有值的。
提前AOP生成代理对象,将此代理对象存入缓存(Map)。
HashMap
这边需要判断是否出现了循环依赖,实际上在初始化a的时候是无法判断的。在初始化b的时候需要a,但是a还是创建中,这时候就可以判断出现循环依赖了。提前进行AOP创建a的代理对象。
这样就可以解决了。
但是如果a依赖b和c,b依赖a,c依赖a,这边创建b和c的时候都需要提前AOP,创建a的代理对象,这边就出现了问题,不符合单例。这边就加一个Map,将提前AOP出来的代理对象放入此Map中,这样就可以先去此Map中找是否已经提前AOP出来a的代理对象。
第三级缓存(singletonFactories)
(Map<beanNmae: lambda(beanName, bd, 原始对象)>)HashMap
AOP的时候需要用到原始对象。
这边的lambda表达式是不会执行的,只是一个定义。
不执行的原因是不知道是否出现了循环依赖,这个lambda执行的话就是在进行AOP。
AOP生成代理对象后放入二级缓存中(这边对象如果不需要进行AOP的话就直接返回原始对象也需要放入二级缓存中),然后移除三级缓存中的这个bean。
为什么三级缓存要移除?
因为要符合单例。原子性。
为什么二级三级缓存是Hashmap,一级缓存是ConcurentHashMap?
因为二级三级缓存需要保证原子性,同时操作,需要加锁,用ConcurentHashMap影响性能。
在这里插入图片描述
正常进行AOP的时候会从一级二级缓存中寻找代理对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值