spring源码bean的创建过程-解决循环依赖-

spring源码-解决循环依赖-bean的创建过程

开始之前,主要是为了解决循环依赖问题,为了方便理解,首先要理清几个概念:

1.一个bean不是一个对象,只有走完整个springbean的声明周期的对象才是bbean
2.spring中一共有三级缓存,一级缓存:singletonObject 二级缓存.singletonfactroy 三级缓存:earlySingletonObjects

点开spring源码,所有的主要方法都在refresh中
在这里插入图片描述
除了上面的容器实例化和后置处理器注册等,通过断电的方式我们可以发现对面的实例化完成实在finishBeanFactoryInitialization(beanFactory);中完成的,点进去
在这里插入图片描述
通过getbean方法获取相应的bean
在这里插入图片描述
点击进来发现是通过doGetBean方法获取
在这里插入图片描述dogetbean方法中首先通过tranformedBeanNamefhfa判断beanname过滤掉非法字符串,让后通过getSingleton方法到单例池中获取bean对象,因为这里时第一次创建,所以肯定是获取不到的
在这里插入图片描述
继续往下走,因为循环依赖肯定时单例的,所以原型判断直接跳过,在判断单例的方法体中,又获取了一次调用getSinglton方法,这也是解决循环依赖一个关键点
在这里插入图片描述这里要注意一下,第一次调用getSingleton的时候和吧eyicidnys的getSingleton不是同一个方法,点进去我们就会发现,首先第一个到单例尺中获取肯定获取不到的 ,毕竟还没有创建,但是这里没有一个关键的方法就是beforeSingletonCreation(beanName);,做一下标记,后面循环依赖的时候回来将,
在这里插入图片描述
既然获取不到,继续回到doGetbean方法中来,只能选择去创建,这个方法执行玩,我们的对象就被实例化了
在这里插入图片描述
点进去看一下实力化的过程,获取对象的name和对象的class,绑定l两者通过
resolveBeforeInstantiation(beanName, mbdToUse)

在这里插入图片描述
烫后通过doCreateBean方法进行对象的创建
在这里插入图片描述
对象的实例化,aop以及装配都在这个方法里完成
在这里插入图片描述
首先通过createInstance放afald实例化对象,点击进去,可以看到spring会通过查看该方法的beanDefination查看是否有可以创建对象的工厂放方法,一个是否有构造器,构造器有没有参数进行判断,如果都没有就使用spring默认的,因为只要是为了解决循环依赖问题,所以就先不进行细究
完成对象的实例化,之后我们回到doCreateBean方法中来
在这里插入图片描述
通过第一行的判断条件allowCircularReferences可以看到spring是支持循环依赖的,吐过支持就将其曝光,上面已经完成实例化了,下面就是进行装配通populate方法进行装配,这也是完成循环依赖核心方法
会通过调用postProcess进行解析自动映射,实现@Autowired和@Resource

这里有一个小细节,就是@autowired和@resource的差别,处理我们直到的就是解析这两个的后置处理器不一样一个是AutoWiredAnnotionPostPreocess一个是CommonAnnotionPostPrrocess

在这里插入图片描述
点进去可以发现还是通过调用getBean方法来获得依赖,继续往后当然是和第一创建的时候一样的
在这里插入图片描述
*getBean->dogetbean->create->doCreteBean-populate-引入这个对象依赖->getbean,在getBean中第一次调用getSinglton的时候,如果按照我们正常的理解步骤下去可能就套娃了,一直出不来,在你ObjectSingleTon中因为这是第一值创建所以我们必定拿不到,进入下一个判断这里的第一个if谈慢性现在就会成立了,还记得我们之前说的留着后面讨论的方法吗==beforeSingletonCreation(beanName)==在第创建第一个对象时候,会通过这个方法将beanname放入到一个容器中,顾名思义,isSingleTonCurrentlyInCreatetion就是正在创建,接下来通过singletonFactory获取工厂对象方法,把他放到三级缓存中,至于为什么放到三级缓存中,简单理解就是为了防止重复创建。总之这里已经通过return进行返回了获取到了个对象。到这里循环依赖完成
*
在这里插入图片描述
回到docreteBean方法中,populate对象注入完毕,接下来的initializeBean处理的时我们在bean生命周期后置处理器@PostProcess以及xml中的init_method以及实现initialzingBean接口的方法,也就是对对象进行处理
在这里插入图片描述
有一个注意点就是第二个对象进行getBean的时候获取的不是一个对象,而是一个工厂方法