spring中bean创建过程框图
2021-09-27 09:01:15 13 举报
spring中关于bean的创建过程
作者其他创作
大纲/内容
二级缓存
提前暴露的对象
Ba
A的初始化给b填充属性
实例化和初始化是分开处理的,当完成实例化之后就可以让其他对象引用当前对象,只不过当前对象不是一个完整对象而已,后续需要完成此对象的剩余步骤
3
比较复杂的通用方法
无参构造
map
半成品缓存
直接获取半成品对象的引用地址,保证对象能够被找到,而半成品对象在堆空间中是否有设置的属性值,无所谓
有参构造实例化
通过factoryMethod创建对象
形成闭环,死循环
key:beanNamevalue:lambda表达式
找不到
通过反射创建对象
当实例化完成之后, 要开始进行初始化赋值操作了,但是赋值的时候,值的类型有可能是引用类型,需要从spring容器中获取具体的某个对象来完成赋值操作,而此时,需要引用的对象可能被创建了,也可能没被创建,如果被创建了,那么直接获取即可,如果没有创建,在整个过程中就会涉及到对象的创建过程,而内部对象的创建过程中又会有其他的依赖,其他的依赖中有可能包含当前的对象,而此时当前对象还没有创建完成,所以此时产生了循环依赖问题。
doCreateBean
完成实例化但是未完成初始化
找到
创建A对象
springcloud
工厂方法实例化
getBean
直接返回赋值即可
如果单纯为了解决循环依赖问题,那么使用二级缓存足够解决问题,三级缓存存在的意义是为了代理,如果没有代理对象,二级缓存足以解决问题
只是beanDefinition的一个属性值
@PreDestroy
JDBC
创建对象
我们在获取完整对象的时候,分为了两个步骤,实例化和初始化,初始化环节的填充属性阶段有没有可能会改变当前对象的地址空间?不会但是,我们不得不考虑另外一种情况,spring在使用的时候会配置AOP,需要生成具体的代理对象1、生成代理对象之前,要不要生成普通对象?要2、我们能否确定什么时候会调用具体的对象?无论是普通对象还是代理对象不能3、有没有可能,在spring中同时存在同一个beanName的普通对象和代理对象?如果有的话,那么我在调用的时候是根据beanName来获取对象,此时我要获取到两个对象吗?那么我应该用哪个?我应该分块存储吧。那么可以创建两个缓存,分别存储普通对象和代理对象4、这两个缓存,我优先获取哪个?优先获取代理对象,然后才是普通对象,错误的结论,代理对象中应该包含了普通对象的所有功能,如果一个对象需要被代理了,那么此时普通对象就可以不存在,只要代理对象即可也就是说,在后续创建代理对象之后,就可以使用代理对象来覆盖普通对象,普通对象可以不存在了回到第二个问题中,什么时候要调用对象?我在调用对象的时候,如果检测到当前对象需要被代理,那么直接创建代理对象覆盖即可怎么能够在随时需要的时候创建代理对象呢?类似于观察者,但是不是,我传递进去一个生成代理对象的匿名内部类,当需要调用的时候,直接调用匿名内部类(lambda)来生成代理对,就是类似于回调机制5、很多同学在刚刚的步骤中说到了初始化,初始化包含了哪些环节?a:填充属性b:执行aware接口所对应的方法c:执行beanPostProcessor中的before方法d:执行init-methode:执行beanPostProcessor中的after方法上述步骤执行完成之后是为了获取到一个完整的成品对象,但是在初始化前我们能确定哪一个对象需要生成代理对象吗?不能确定,而且我们三级缓存只是一个回调机制,所以能否把所有的bean所需的创建代理对象的lambda表达式都放到三级缓存中?可以将所有bean对象需要的创建代理对象的lambda表达式放到三级缓存中,后续如果我需要调用,直接从三级缓存中掉用执行即可,如果不需要,在生成完整对象之后可以把三级缓存中lambda表达式给清除掉(往一级缓存中放成品对象的时候就可以清除)6、我在什么时候要生成具体的代理对象呢?(代码实操)a:在进行属性注入的时候,调用该对象生成的时候检测是否需要被代理,如果需要,直接创建代理对象b:在整个过程中,没有其他的对象有当前对象的依赖,那么在生成最终的完整对象之前生成代理对象即可(BeanPostProcessor中的after方法)
B
完成实例化但未完成初始化的对象
Simple实例化策略
反射
初始化和循环依赖
实例化策略
接口规范实现
B的初始化给a填充属性
spring
生成代理对象的缓存
直接返回,赋值即可
cglib实例化策略
一级缓存
时间最久
随便定义创建对象的方法,不止局限于getObject
存放对象
成品缓存
baseMapper
通过supplier创建对象
从容器中查找A对象
A的实例化普通对象,属性值为默认值
无参构造实例化
动态代理对象
从容器中查找B对象
AutowiredAnnotationBeanPostProcessor
成品: 普通不需要代理的对象,代理对象
Ab
抽象出一个接口规范,所有的对象必须要通过getObject方法获取
只实例化但未初始化的对象
@Autowired
before
doGetBean
半成品
有没有可能直接从三级缓存到一级缓存?有
tomcat
代理对象
springboot
如何解决循环依赖问题?
有参构造
@PostConstruct
springmvc
B的实例化普通对象,属性值为默认值
BeanPostProcessor
@Resource
加载注解的相关解析配置工作
@Value
2
1
savedeleteupdateselect
三级缓存在进行对象查找的时候,顺序是什么样的?
有相似之处
after
成品
key:beanNamevalue:Object
通过FactoryBean创建对象
CommonAnnotationBeanPostProcessor
缓存
创建B对象
A
createBean
orm
三级缓存
InitDestroyAnnotationBeanPostProcessor
0 条评论
下一页