缺省情况下,一个Spring bean
是单例模式的,也就是说,在整个Spring
容器中,该bean
只有一个。并且一个单例bean
会在第一次从容器获取时被创建,随后再次从容器获取时返回的其实是已经创建好的实例。Spring
创建bean
的过程,并不是简单地使用Java new
关键字创建一个POJO
对象,相反,除了创建POJO
对象之外,Spring
还会对所创建的bean
对象进行必要的代理包装,执行生命周期回调方法,设置属性,进行依赖注入等等。尤其是这里依赖注入的执行,这是Spring
框架赖以成功的核心概念。
这篇文章总结一下单例bean
的创建过程,以备开发人员参考:
- 根据
bean
名称获取MergedBeanDefinition
如果
bean
定义是一个ChildBeanDefinition
或者parentName
不为空的GenericBeanDefinition
,则需要合并当前bean
定义和祖先bean
定义生成一个"合并了的"MergedBeanDefinition
,然后基于此MergedBeanDefinition
进行bean
创建。 - 获取所依赖的
bean
的名称并确保这些bean
被创建也就是类似注解
@DependsOn
所指定的bean
,这里所谓"确保这些bean
被创建"其实是递归调用容器获取这些bean
从而触发它们的创建过程 - 获取创建
bean
所要使用的实现类 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
在这一步有可能直接返回另外一个对象(比如代理对象)代替该
bean
完成该bean
的各种功能。- 实例化
可以认为相当于使用
Java new
关键字创建一个对象,实际上可能是通过反射,或者调用工厂方法 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
可以参考
AutowiredAnnotationBeanPostProcessor
以助于理解在该生命周期节点可以做些什么事情。- 属性填充(依赖注入) –
populateBean
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor#postProcessProperties
@Autowired
/@Inject
/@Value
依赖注入就是在这里完成的,具体来讲,是通过o.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
- 应用
BeanDefinition
中的属性bean
的创建来自bean
定义,也就是BeanDefinition
,BeanDefinition
也以对象形式存在,通常由框架提供,其中也会有需要填充到最终bean
的属性,这一步骤应用的就是这些属性
- 初始化 –
initializeBean
invokeAwareMethods
调用各种Aware
接口定义的方法BeanPostProcessor#postProcessBeforeInitialization
invokeInitMethods
调用初始化方法(可能有多个)InitializingBean#afterPropertiesSet
- 定义中指定的自定义初始化方法
如果和
InitializingBean#afterPropertiesSet
同名则不会被调用
BeanPostProcessor#postProcessAfterInitialization
registerDisposableBeanIfNecessary
如果该
bean
定义含有销毁回调,则将该bean
登记起来,在容器销毁bean
阶段执行相应的回调