Spring源码分析_2 Bean生命周期原理
作者:田超凡
版权所有,严禁复制转载
1 Bean生命周期原理图
2 Bean生命周期实现原理
- AnnotationConfigApplicationContext 带参构造调用refresh()方法初始化SpringIOC容器
- refresh()中的finishBeanFactoryInitialization()实现Bean扫描、加载、创建、注册和生命周期管理
注意:SpringIOC容器启动时默认只会加载和创建声明作用域为单例的Bean并存入beanDefinitionMap中,对于多例的Bean容器在启动时不会自动扫描和创建。
SpringIOC容器注册Bean默认开启了延迟加载@Lazy(value=true),即容器启动时只是加载Bean而不创建和初始化,不会调用构造函数
如果指定的Bean声明了非延迟加载@Lazy(value=false),则表示需要立即加载的Bean,对于这一类Bean,SpringIOC容器会在加载Bean之后立即创建和初始化,调用目标Bean的构造函数
Bean生命周期流程:
- preInstantiateSingletons
- getBean
- doGetBean
- getSingleton Bean循环依赖解决方案
- createBean
- doCreateBean
- createBeanInstance 基于反射加载和创建Bean实例
- addSingletonFactory 将注册好的Bean放入三级缓存
- populateBean 基于反射给Bean属性赋值,实现Dependency Inject依赖注入
- initialBean 实现Bean初始化策略
- invokeAwareMethods 校验Bean的Aware上下文环境,调用实现了ApplicationContextAware的Bean的初始化方法
- postProcessBeforeInitialization Bean初始化前置增强
- initMethodInvoke 执行初始化方法init、afterPropertiesSet
- postProcessAfterInitialization Bean初始化后置增强,实现Spring AOP创建代理实例和实现声明式事务处理
3 Bean生命周期源码分析
1 首先调用AnnotationConfigApplicationContext中的refresh()方法初始化SpringIOC容器,在refresh中调用finishBeanFactoryInitialization()方法实现Bean的加载创建注册和管理
2 调用beanFactory的preInstantiateSingletons()加载并创建单例的Bean
3 在DefaultListableBeanFactory的preInstantiateSingletons()方法中会先校验需要注册的Bean是否声明的是单例的Bean、是否开启延迟加载、是否是使用FactoryBean工具Bean创建
4 依次调用getBean() -> doGetBean() 加载并创建Bean,注册到Spring IOC容器中;对于已经创建的bean则直接从Spring IOC容器中根据beanId获取Bean即可
5 首先会获取当前beanName指向的beanId,然后调用getSingleton()从Spring IOC容器中获取已经注册的单例Bean,如果需要获取的单例Bean正在初始化,此时获取未初始化完毕的Bean会抛出异常
Set<Object> singletonsCurrentlyInCreation 标记正在初始化的Bean
如果需要创建的Bean是多例的,且Bean存在和其他Bean循环依赖的情况,也会直接报错,因为SpringIOC容器无法知道使用当前Bean的哪一个实例来建立和另一个Bean的循环依赖
单例Bean是一定不会存在这个问题的,因为单例Bean会直接在getSingleton()方法中建立和另一个Bean的循环依赖关系,通过三级缓存去实现具有循环依赖关系的Bean的注入和注册
6 对于getSingleton()没有获取到Bean实例的情况下,需要加载并创建Bean,注册到SpringIOC容器中。
依次调用createBean() -> doCreateBean() 创建Bean
在createBean()方法中会先获取Bean类型,基于类加载器双亲委派机制获取Bean类型定义,然后会创建默认的RootBeanDefinition作为当前需要创建的Bean的默认bean定义
会先尝试从RootBeanDefinition中获取Bean实例,调用BeanPostProcessor的前置增强获取执行结果,如果结果都为空则认为Bean初始化前的前置增强没有定义创建Bean的实现,所以继续调用doCreateBean()开始正式创建目标Bean实例
调用doCreateBean开始正式创建Bean实例并执行初始化操作,doCreateBean方法是整个Bean生命周期管理的核心,该方法主要做4件事:
(1) createBeanInstance() 基于反射创建Bean实例
(2) addSingletonFactory() 将创建好的Bean实例放入到循环依赖的三级缓存中(singletonFactorys)
(3) populateBean() 基于反射给Bean的属性注入值,也是Dependency Inject依赖注入的核心实现方法
(4) initializeBean() 执行Bean实例的初始化操作
首先,调用createBeanInstance()基于反射创建Bean实例
创建Bean实例,基于构造函数创建或者直接基于反射创建
调用SimpleInstantiationStrategy instantiate()创建Bean实例
调用addSingletonFactory将创建好的Bean实例存入三级缓存singletonFactorys
调用populateBean(),基于反射给Bean实例的属性注入默认值或依赖值,实现Dependency Inject依赖注入
调用initializeBean()执行Bean初始化操作
调用invokeAwareMethods(),校验Bean绑定的Aware上下文,调用ApplicationContextAware的初始化方法
调用BeanPostProcessor的postProcessBeforeInitialization()实现前置增强、调用目标Bean的自定义初始化方法(init()、afterPropertiesSet())、postProcessAfterInitialization()实现后置增强
至此,Bean生命周期管理流程执行完毕。
总的来说,Bean生命周期分为五个步骤:加载、创建、初始化、服务、销毁
补充说明:
1 创建并初始化完成的Bean会存入DefaultListableBeanFactory的Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();中
2 需要获取SpringIOC容器中的Bean时即可通过ApplicationContext getBean()根据beanId来获取IOC容器中的Bean
3 SpringIOC容器停止运行时会将容器中的Bean全部销毁,调用DepositBean的destory()实现Bean销毁和资源释放