Bean的示例化在Spring的启动过程中基本上算是最后的步骤。经过了前面BeanDefinitionRegistryPostProcesser和BeanFactoryPostProcessor注册BeanDefintion,registerBeanPostProcessors方法注册BeanPostProcessor。到了最后实例化的过程。
实例化的过程经过一下几层调用:AbstractApplicationContext.finishBeanFactoryInitialization -> DefaultListableBeanFactory.preInstantiateSingletons ->AbstractBeanFactory.getBean ->AbstractBeanFactory.doGetBean
简单来说就是先获取当前所有的beanDefinitionNames,根据beanDefinitionNames调用AbstractBeanFactory.doGetBean来实例化bean。
OK,我们来分析一下doGetBean的过程,这是一个复杂的过程。
首先调用getSingleton方法在已注册的单例列表中寻找给定名称的单例并返回。
如果返回的不是null,说明这个bean已经注册为单例了,于是调用getObjectForBeanInstance返回给定bean实例的对象,如果是FactoryBean则返回它创建的对象,否则返回bean实例本身。
如果getSingleton方法返回的是null,则说明这个bean没有被注册为单例。于是开始另外的步骤:
- 调用
getParentBeanFactory方法返回父级bean factory。如果父级bean factory不为null,则调用父级bean factory的getBean方法来获取bean并返回。 - 调用
getMergedLocalBeanDefinition来获取bean definition。 - 调用
BeanDefinition.getDependsOn方法获取这个bean依赖的bean的名称。如果依赖的bean不为空,则调用registerDependentBean来注册这个bean所依赖的bean,这样当这个bean被销毁时同时销毁这些依赖的bean。然后调用getBean来实例化这些依赖的bean - 如果bean是单例。调用
getSingleton方法返回该bean的单例,接着调用getObjectForBeanInstance返回给定bean实例的对象,如果是FactoryBean则返回它创建的对象,否则返回bean实例本身。 - 如果bean是原型(
prototype)。先调用beforePrototypeCreation执行原型创建前的回调,然后调用createBean创建bean实例,接着调用afterPrototypeCreation执行原型创建后的回调。最后调用getObjectForBeanInstance返回给定bean实例的对象,如果是FactoryBean则返回它创建的对象,否则返回bean实例本身。 - 如果bean既不是单例也不是原型,则在其
scopesmap中获取另外的scope,然后调用scope的get方法获取bean实例,最后调用getObjectForBeanInstance返回给定bean实例的对象,如果是FactoryBean则返回它创建的对象,否则返回bean实例本身。
DefaultSingletonBeanRegistry.getSingleton
bean的实例化过程中最核心的方法是:getSingleton,其中的调用方式是:
1 | sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { |
可以看到调用getSingleton方法的同时传入一个ObjectFactory,其中getObject方法中调用createBean方法来创建bean实例。
首先来看getSingleton本身:
- 首先从
beanFactory的singletonObjects中获取相应名称的单例bean。如果返回的单例bean不为null则直接返回,否则进入后面的步骤。 - 调用
beforeSingletonCreation执行单例创建前的回调 - 调动
singletonFactory.getObject方法获得单例实例 - 调用
afterSingletonCreation执行单例创建后的回调 - 调用
addSingleton方法将给定的单例对象添加到factory的单例缓存中
createBean
可以看到创建单例的过程中最核心的步骤是调用singletonFactory.getObject方法获得单例实例,而getObject调用的是AbstractAutowireCapableBeanFactory.createBean方法创建bean实例。
我们来分析一下这个核心方法:
- 调用
resolveBeanClass方法,确保bean class被真正地解析。然后克隆一份bean definition - 调用
AbstractBeanDefinition.prepareMethodOverrides方法,验证并准备方法重写。 - 调用
resolveBeforeInstantiation方法,在bean初始化前调用BeanPostProcessor的postProcessBeforeInstantiation。如果调用postProcessBeforeInstantiation方法之后返回了一个非null的bean,则马上调用BeanPostProcessor的postProcessAfterInitialization方法,如果这1次/2次调用之后返回的bean非null,则返回这个bean。否则进入下面的步骤。 - 最后调用
doCreateBean方法,得到创建的实例并返回
doCreateBean
这是真正创建bean的方法。它的步骤如下:
- 调用
createBeanInstance方法,为特定的bean创建一个新的实例,使用恰当的实例化策略:工程方法,构造函数自动装配,简单实例化 - 根据
createBeanInstance方法返回的BeanWrapper类型,获取对实例象以及对象Class - 对bean定义调用
MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法 - 调用
populateBean,使用bean definition中的属性值来填充bean实例 - 调用
initializeBean,初始化给定的bean实例,包括调用factory的回调,以及init方法和bean post processor - 最后调用
registerDisposableBeanIfNecessary
下面分别对用到的几个核心方法做分析
createBeanInstance
- 调用
resolveBeanClass确保bean class已经被解析过了。 - 如果bean中有工厂方法,则返回调用
instantiateUsingFactoryMethod方法返回使用工厂方法实例化的bean。否则进入下面的步骤 - 如果bean基于构造器的依赖关系,则调用
autowireConstructor方法使用构造器实例化bean并返回 - 否则,调用
instantiateBean使用默认的构造器实例化给定的bean并返回
populateBean
- 调用
getPropertyValues方法获取属性值 - 调用
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation来处理实例化之后的bean - 如果bean是通过名称进行依赖注入的,则调用
autowireByName填充缺失的属性值;如果bean是通过类型进行依赖注入的,则调用autowireByType填充缺失的属性值。 - 调用
InstantiationAwareBeanPostProcessor.postProcessPropertyValues在属性值被赋予bean之前处理给定的属性值 - 最后调用
applyPropertyValues应用属性值
initializeBean
- 调用
invokeAwareMethods。如果bean实现了BeanNameAware接口,调用setBeanName设置bean名称;如果bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader设置classLoader;如果bean实现了BeanFactoryAware接口,调用setBeanFactory设置beanFactory - 调用
BeanPostProcessor的postProcessBeforeInitialization方法 - 调用
invokeInitMethods,检查bean是否实现了InitializingBean,或者自定义了一个init方法,如果有则调用必要的回调函数。 - 调用
BeanPostProcessor的postProcessAfterInitialization方法