在执行DefaultListableBeanFactory#preInstantiateSingletons方法时会创建非懒加载的单例Bean,这个创建过程是通过调用AbstractBeanFactory#getBean(java.lang.String)创建的;
下面分析AbstractBeanFactory#getBean(java.lang.String)的执行流程;

该方法是一个空壳方法,没有任何的实现逻辑 真正的逻辑调用在doGetBean()中,该接口是实现了BeanFactory的getBean(String name)接口;
首先通过调用transformedBeanName(name)获取beanName;
调用getSingleton(beanName)尝试从缓存中获取对象;
判断条件(sharedInstance ! = null && args == null)是否成立,成立则调用getObjectForBeanInstance(sharedInstance, name, beanName, null)返回Bean实例;如果sharedInstance 是普通的单例bean,方法会直接返回bean实例;如果sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的bean实例;
条件(sharedInstance ! = null && args == null)不成立,则走下面的逻辑;
调用isPrototypeCurrentlyInCreation(beanName)判断是否存在多例对象(prototype:多例对象,IOC容器启动的时候,IOC容器启动并不会去调用方法创建对象, 而是每次获取的时候才会调用方法创建对象)的循环依赖,存在则抛出BeanCurrentlyInCreationException异常;
注:Spring解决了单例对象的属性注入的循环依赖,而构造器注入的循环依赖没有解决;
创建两个循环依赖的多例Bean,如下:
异常如下:
getParentBeanFactory()判断AbstractBeanFacotry工厂是否有父工厂(一般情况下是没有父工厂因为AbstractBeanFactory直接是抽象类,不存在父工厂),存在则根据父工厂调用getBean,一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念;
调用getMergedLocalBeanDefinition(beanName)会合并父BeanDefinition和子BeanDefinition,子BeanDefinition会覆盖父BeanDefintion;
测试如下:
bean.xml
执行结果如下:
将bean.xml中注释打开,执行结果如下:
处理Bean加载依赖顺序,如果dependsOn不为空,则调用registerDependentBean(dep, beanName)注册该Bean的依赖项,getBean(dep)优先创建依赖的对象;
之后根据BeanDefinition的scope类型创建Bean实例;
下面分析scope为single类型的Bean实例创建;
调用getSingleton(beanName, new ObjectFactory<Object>(){})获取单例对象;
首先从单例缓存池中获取Bean实例,如果Bean实例存在,则将对象返回,否则执行创建对象的逻辑;
调用beforeSingletonCreation方法标记当前bean要被创建,该方法在Bean创建前调用的;
singletonsCurrentlyInCreation 在这里会把beanName加入进来,标记该Bean正在创建,当第二次进入时,如果出现singletonsCurrentlyInCreation 添加失败,这个时候出现了循环依赖(构造器注入);
ObjectFactory类型的入参singletonFactory调用getObject方法,用于返回一个Bean的实例;
在最后会调用afterSingletonCreation将singletonsCurrentlyInCreation标记正在创建的bean从集合中移除,addSingleton将创建的Bean实例加入到缓存中
而getSingleton方法的入参是一个函数接口,执行创建的逻辑在createBean方法;
这里会调用resolveBeforeInstantiation方法,在注释中的意思是给后置处理器返回一个代理对象,但一般情况下在此次是不会返回代理对象的,不论是使用JDK代理还是Cglib代理,前提条件需要有一个Bean实例,而此时的Bean实例并没有创建,代理对象并不会生成,这里只是将用户定义的切面信息进行缓存;
之后执行doCreateBean方法,创建Bean实例的流程在这里;
调用createBeanInstance方法,使用合适的实例化策略创建实例;
判断传入的mbd.getFactoryMethodName是否为空,即有无使用@Bean通过工厂方法注入实例;
mbd的factoryMethodName在BeanDefiniton加载时赋值的,如下:
ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod
判断Bean定义信息中的resolvedConstructorOrFactoryMethod是否缓存,因为需要根据参数确认到底使用哪个构造器,该过程比较消耗性能,所有采用缓存机制;
通过Bean的后置处理器进行获取合适的构造器对象,根据相应的策略创建对象并返回;
Spring中有三级缓存,用于解决属性赋值的循环依赖;
此时创建出来的Bean没有进行属性赋值的,属于早期对象,isSingleton表示是否为单例,allowCircularReferences默认为true,isSingletonCurrentlyInCreation表示当前beanName的Bean正在创建;
符合条件则调用addSingletonFactory方法,该方法把早期对象包装成一个ObjectFactory暴露到三级缓存中;
调用populateBean进行属性赋值;
对象的属性注入是通过后置处理器处理的;
如@Autowired的属性注入是通过AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues处理的;
伪代码如下:
上面的伪代码ComponentB是ComponentA的字段值,需要自动注入;
后置处理器最终会根据注入的类型执行下面的注入逻辑,如字段的注入,执行AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject方法;
AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
这里会获取字段值的实例对象,并把该字段实例对象set到依赖该对象的Bean上;
最终通过org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate获取需要依赖的Bean的实例对象,其实该方法是通过BeanFactory#getBean获取Bean的实例对象;
调用initializeBean进行对象初始化;
AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
invokeAwareMethods会将实现了XXXAware接口进行方法的回调,invokeInitMethods方法会将实现InitializingBean接口或@PostConstruct注解修饰的方法进行回调,applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization则会对BeanPostProcessor接口申明的方法进行回调;
调用registerDisposableBeanIfNecessary方法,注册销毁Bean的接口DisposableBean,当Bean生命周期结束时会对该接口的destroy方法进行回调;