Spring源码分析_2 Bean生命周期原理

                                                                       Spring源码分析_2 Bean生命周期原理

                                                                                                                                                                                                                                                                                   作者:田超凡

                                                                                                                                                                                                                                                                                   版权所有,严禁复制转载

 

1 Bean生命周期原理图

 

 

2 Bean生命周期实现原理

  1. AnnotationConfigApplicationContext 带参构造调用refresh()方法初始化SpringIOC容器
  2. 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销毁和资源释放

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值