说明:因为贴代码会让文章变的繁杂,为了更连续的说明,代码就不贴出来了,可以根据下面的入口方法看着笔记去了解这个过程
AbstractBeanFactory{
public Object getBean(String name) throws BeansException {return this.doGetBean(name, (Class)null, (Object[])null, false);
}
}
---------------------------------------------正文开始昂!-----------------------------------------------@Component | @Component
public class X{ | public class Y{@Autowire | @Autowireprivate Y y; | private X x;
} | }注意:注意singletonObject和bean的区别:
Object singletonObjects=singletonObjects.get(String beanName)
bean=getObjectForBeanInstance(Object beanInstance,String name,String beanName,RootBeanDefinition mbd);spring启动,调用链-->refresh-->finishBeanFactoryInitialization-->beanFactory.preInstantiateSingletons()
beanFactory.preInstantiateSingletons()中根据遍历beanDefinitionNames去调用getBean(String beanName)方法;
getBean-->doGetBean();假设先扫描到了组件X:doGetBean方法首先会调用getSingleton(String beanName);
getSingleton(String beanName)-->getSingleton(beanName,true):
即protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {synchronized(this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}
方法首先调用Object singletonObject=this.singletonObjects.get(String beanName),若果singletonObject为null并且"当前bean正在被创建"时
-->singletonObject=this.earlySingletonObjects.get(String beanName),如果singletonObject为null并且允许提前引用
-->ObjectFactory<?> singletonFactory=this.singletonFactories.get(String beanName),如果singletonFactory!=null
-->singletonObject=singletonFactory.getObject(),getObject()是一个函数式接口,里面会调用doCreateBean()
this.earlySingletonObjects.put(String beanName,Object singletonObject)
this.singletonFactories.remove(String beanName)
-->return singletonObject
此次是第一次调用getSingleton方法,"当前bean没有正在创建",所在getSingleton的第一步Object singletonObject=this.singletonObjects.get(String beanName)时就返回一个为null的singletonObject;接下来会合并当前beanDefinition对象,然后判断该beanDefinition是否是单例的,如果是则spring会调用方法:
getSingleton(beanName,()->{
createBean(beanName,beanDefinition,args)
})
即getSingleton(String beanName,ObjectFactory<?> singletonFactory);
其中ObjectFactory<?>是一个函数式接口,里面只有一个getObject方法;
getSingleton(String beanName,ObjectFactory<?> singletonFactory)进入后首先:
Object singletonObject=this.singletonObjects.get(beanName);
此时因为是第一次调用,所以singletonObject为null,当singletonObject为null时会进入一个if断码段;
该代码段首先会执行beforeSingletonCreation(),该方法会将此beanName标志成"正在创建中";
然后调用singletonFactory.getObject()方法,也就是前面传入的函数式接口方法,即最终调用到createBean()方法;
crateBean调用到doCreateBean,在doCreateBean中首先final Object bean=instanceWrapper.getWrapperInstance();
然后判断判断当前beanDefinition是否是单例且是允许提前暴露引用且是正在被创建,如果条件满足则
会调用addSingletonFactory(beanName,()->getEarlyBeanReference(beanName,beanDefinition,bean))方法,该方法内容如下:
addSingletonFactory(String beanName,ObjectFactory<?> singletonFactory){Assert.notNull(singletonFactory,"Singleton factory must not be null");synchronized(this.singletonObjects){if(!this.singletonObjects.containKey(beanName)){this.singletonFactories.put(beanName,singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}
}
继而调用populateBean(beanName,beanDefinition,instanceWrapper),此方法就是实现了bean的自动注入的方法;
当X的bean实例化过程中调用到了populateBean后,因为X依赖Y,所以在populateBean内部会调用getBean("y");
相同的,Y从getBean(beanName)开始,和上面经过一模一样的步骤,然后走到了populateBean方法,然后又以为Y依赖X,所以又会调用getBean("x");
此时此刻的getBean("x")就和第一次执行getBean("X")不一样了;
getBean(beanName)-->doGetBean():
doGetBean首先调用的代码:Object sharedInstance=getSingleton(beanName);
这个时候的getSingleton(beanName)因为单例池中没有x,而且x是正在被创建,又因为earlySingletonObjects中没有x,x又允许提前暴露,
所以代码最终会到:
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);
}
因为x调用doCreateBean的时候调用了addSingletonFactory(String beanName,ObjectFactory<?> singletonFactory)所以这个时候的
singletonFactory不为null,即代码会调用到singletonFactory.getObject(),这个getObject()方法即为getEarlyBeanReference(beanName,beanDefinition,bean)方法;
然后拿到了singletonObject并将其放入earlySingletonObjects中,在将singletonFactories中的工厂对象删除,见如上代码;
执行完后,sharedInstance不为null,则不会在调用x的创建逻辑,而是直接返回所需要的bean对象,返回后Y的populateBean方法也会正常退出,
Y执行完populateBean后返回创建到的bean对象,此时Y注入了earlySingletonObjects中的X——也就是getEarlyBeanReference(beanName,beanDefinition,bean)得到对象,
也即X创建过程中执行populateBean方法前创建的那个对象当Y返回后,执行逻辑回到最开始X的populateBean,执行完populateBean之后,X也已经成功注入了Y,即循环引用的bean创建完成;