spring的流程以及循环依赖问题
2022-09-26 08:58:47 0 举报
spring的流程以及循环依赖问题
作者其他创作
大纲/内容
创建B对象
读取器
BeanFactory
dom4jsax
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { /** * * @param beanFactory 可配置列表Bean工厂 * @throws BeansException */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); //通过可配置的Bean工厂的名字去找到对应的bean的定义信息 BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName); //可以通过这个bean的定义信息进行相关的操作 beanDefinition.setDependsOn(); } }}
doGetBean
BeanFactoryPostProcessor
实例化Ab-null
为什么需要三级缓存?AOP为什么
从容器中查找B对象
三级缓存
aware类
3个map
注解
。。。
context.getBean(xx.class)
生成BeanDefition
xml文件
Spring如何加载配置文件
从容器重查找A对象
转换成Document
1,BeanPostProcessor中有俩重要的方法,且这是一个接口2,她的有一个实现类叫AbstractAutoProxyCreator,这个方法中有一个必须实现的方法叫做createProxy,这个方法中有一个ProxyFactory3,ProxyFactory中有一个getProxy方法。点击进入getProxy4,进入到AopProxy接口,他的实现类就是JDK动态代理类和Cglib动态代理
creatBeanInstance
public class MyTest { public static void main(String[] args) { ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(\"mybatis-config.xml\"); }}
属性填充set方法设置值
1,所有的PostProcessor都是增加器,用于完成用户自定义操作2,用户需要实现一个自定义一个bean的后置处理器,我们就需要实现这个接口代码如下
BeanPostProcessor
通过继承这个接口去将调用权交给Bean容器
BeanDefinitionReader
找到了
构造器
BeanFactory通过反射进行创建对象
创建A对象
jdk
循环依赖问题
填充A对象的b属性
FactoryBean是一个特殊的接口,他里面有一个重要的方法getObject这个接口的作用是生成一个用户自定义的不需要按照标准bean周期的bean对象
A对象 a有b属性
creatBean
进入ClassPathXmlApplicationContext
AOP是在BeanPostProcessor中实现的
通过IO流
进入AbstractApplicationContext
getBean
半成品A
找不到
map
循环依赖问题无法解决
bean实例化
Class clazz = Person.class;Constructor ctor = clazz.getConstructor;Object obj = ctor.newInstance;
属性赋值
cglib
对不同的元素进行解析工作
set
读取
B对象 b有a属性
直接赋值
xml
通过三级缓存来哦解决
之前因为我们一直无法创建完整的对象,所以一直走的闭环但是现在只要将半成品的对象放入缓存中,方便后续调用只要有了当前对象的引用地址,后续也可以进行赋值半成品对象放入map缓存结构中,那么能否将成品或者半成品对象放在一起?如果放在一起,就会导致获取对象的时候获取到半成品为了将成品对象和半成品对象完全的区分开,那么可以创建两个缓存对象,可以有多级缓存
此时这个Bean实例是null的
提前暴露对象
实例化Ba-null
创建bean流程
填充B对象的a属性
doCreatBean
通过底层代码验证
populateBean
完整对象
Spring中,对象bean默认都是单例的,意味着整个容器中只有一个对象只要能打破闭环就解决了循环依赖问题左图表示,如果A对象中有b属性,而B对象中有A属性,那么再创建对象时就会产生一个A等b创建,B要等A创建的闭环操作,进行不间断循环
1,三级缓存中存放的什么对象? 1,成品对象 2,半成品对象 3,lambda表达式2,如果只是用一级缓存行不行? 不行,因为半成品和成品对象放在一起,在进行对象获取的时候可能获取到半成品对象,这样的对象式没办法使用3,如果只有二级缓存行不行? getSingleton doCreatBean 只有二级缓存的时候也可以解决循环依赖的问题 添加AOP实现之后,报错,This means that said other beans do not use the final version of the bean 没有使用最终版本的bean对象4,三级缓存存在到底做了什么事? 如果一个对象需要被代理,生成代理对象,那么整个对象需要预先生成非代理对象吗? 需要 三级缓存到底做了什么? lambda.getEarlyBeanReference()只要搞清楚整个方法的具体执行逻辑即可 在当前方法中,有可能会用代理对象替换非代理对象,如果没有三级缓存的话,那么就无法得到代理对象,换句话说 在整个容器中,包含了同名对象的代理对象和非代理对象,你觉得可以吗? 容器中,对象都是单例的,意味着根据名称只能获取一个对象的值,此时同时存在两个对象的话选择哪个?无法确定 设疑无法确定什么时候会调用当前对象,是在其他对象的执行过程中来进行调用的,而不是个人指定的,所以必须要保证容器中如何时候都只有一个对象供外调用,所以在三级缓存中,完成了一件代理对象替换非代理对象的工作,确定返回时唯一的对象。三级缓存是为了解决在aop代理过程中产生的循环依赖问题,如果没有aop的话,二级缓存足矣解决依赖循环问题。
bean初始化用户自定义初始化方法init-method
遍历每一个子元素,来进行解析操作
bean定义信息BeanDefinition
半成品B
遍历
找到对应的处理器handler
收藏
收藏
0 条评论
下一页