【spring源码分析】之bean的生命周期

流程图:

【spring源码分析】之bean的生命周期_第1张图片

【spring源码分析】之bean的生命周期_第2张图片

共有13个阶段

一、Bean元信息配置阶段

Bean信息定义有4中方式

  1. API方式
  2. Xml文件方式
  3. Properties文件方式
  4. 注解方式

API方式:

是通过实现BeanDefinition接口的方式,具体的实现类有5种:

  • RootBeanDefinition:根bean定义信息。表示没有父bean的bean
  • ChildBeanDefinition:子bean定义信息。需要通过parentName属性来指定父bean
  • GenericBeanDefinition:通用bean定义信息。既可以表示没有父bean的bean,也可以表示有父bean的子bean信息。也有parent属性。
  • ConfigurationClassBeanDefinition:配置类中@bean方法定义的bean信息。
  • AnnotatedGenercBeanDefinition:通过注解方式定义的bean信息

直接实例化即可。

Xml方式:


    

最终也会通过XmlBeanDefinitionReader类解析成API的配置方式

Properties文件方式:

employee.(class)=MyClass       // 等同于:
employee.(abstract)=true       // 等同于:
employee.group=Insurance       // 为属性设置值,等同于:
employee.usesDialUp=false      // 为employee这个bean中的usesDialUp属性设置值,等同于:等同于:

最终也会通过 PropertiesBeanDefinitionReader类解析成API的配置方式

注解方式:

@bean或@Compontent最终也会解析成API的配置方式

二、Bean元信息解析阶段

元信息解析主要有3中方式:

  1. xml文件定义bean的解析(XmlBeanDefinitionReader)
  2. properties文件定义bean的解析(PropertiesBeanDefinitionReader)
  3. 注解方式定义bean的解析(PropertiesBeanDefinitionReader)

三、将Bean注册到容器中

bean注册接口:BeanDefinitionRegistry  (继承了AliasRegistry

别名注册接口:AliasRegistry

前三步是在创建ioc容器的时候发生,下面四步到十步是在getBean的时候发生

四、BeanDefinition合并阶段

bean定义可能存在多级的父子关系,递归合并成一个包含完整信息的RootBeanDefinition。

合并处的源码如下:

之后的阶段将使用这个RootBeanDefinition,下一步将检查是否需要加载依赖Bean,没有则跳过(图未截取全)

五、Bean Class加载阶段

将bean的class名称转换为Class类型的对象。

源码如下:

【spring源码分析】之bean的生命周期_第3张图片

具体的resolveBeanClass方法,往下深入,可以看到最终是通过Class.forName获取的类对象

【spring源码分析】之bean的生命周期_第4张图片

【spring源码分析】之bean的生命周期_第5张图片

有了类对象下面就可以开始通过反射进行实例化了

六、Bean实例化阶段

(1)实例化之前

会执行实现了BeanPostProcesstor接口的类的postProcessBeforeInitialization方法。

源码如下:

【spring源码分析】之bean的生命周期_第6张图片

【spring源码分析】之bean的生命周期_第7张图片

可以看出,如果返回了Bean,则spring就会直接使用此bean,而跳过下面创建bean的操作了(这是spring的一个扩展点)

(2)实例化

这个过程会通过反射来调用bean的构造器来创建bean的实例,最后包装成BeanWrapper。(使用了装饰器模式)

源码如下:

【spring源码分析】之bean的生命周期_第8张图片

这里使用了策略模式,在SimpleInstantiationStrategy类中处理

最后在BeanUtils类的InstantiateClass方法中调用的类的newInstance方法(核心)

【spring源码分析】之bean的生命周期_第9张图片

七、合并后的BeanDefinition处理

后置处理类进行一些缓存处理,方便后面使用

【spring源码分析】之bean的生命周期_第10张图片

【spring源码分析】之bean的生命周期_第11张图片

主要是对实现了MergedBeanDefinitionPostProcessor这个接口的类进行回调处理,实现类主要包括:

【spring源码分析】之bean的生命周期_第12张图片

  • AutowiredAnnotationBeanPostProcessor 对@Autowired和@Value标注的字段或方法 进行缓存处理,方便后面使用
  • CommonAnnotationBeanPostProcessor 对@Resource标注的字段或方法、@PostConstruct标注的方法、@PerDestroy标注的方法进行缓存处理

八、属性赋值阶段

(1)实例化后阶段

【spring源码分析】之bean的生命周期_第13张图片

spring会调用实现了InstantiationAwareBeanPostProcessor接口的类的postProcessAfterInstantiation方法

【spring源码分析】之bean的生命周期_第14张图片

如果返回false,则后面的两步属性赋值就会跳过。所以可以用来阻止属性赋值

(2)Bean属性赋值前阶段

主要是通过@Autowire等注解生成属性的值,以便后面进行赋值

【spring源码分析】之bean的生命周期_第15张图片

可以看出当postProcessProperties和postProcessPropertyValues都返回空时,表示此bean不需要设置属性,直接返回,进入下一阶段。

PropertyValues中保存了bean实例对象中所有属性值的设置,所以我们可以在这个postProcessProperties中对PropertyValues值进行修改

InstantiationAwareBeanPostProcessor的实现类如下:

【spring源码分析】之bean的生命周期_第16张图片

最关键是这两个实现类值的注入操作:

  • AutowiredAnnotationBeanPostProcessor@Autowired和@Value标注的字段或方法注入值
  • CommonAnnotationBeanPostProcessor 对@Resource标注的字段或方法注入值

(3)bean的属性赋值阶段

循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。

【spring源码分析】之bean的生命周期_第17张图片

【spring源码分析】之bean的生命周期_第18张图片

九曲十八弯之后,最终调用的是BeanWrapperImpl的setValue方法中通过反射为字段赋值

九、Bean初始化阶段

【spring源码分析】之bean的生命周期_第19张图片

(1)Bean Aware接口回调

【spring源码分析】之bean的生命周期_第20张图片

(2)Bean初始化前操作

【spring源码分析】之bean的生命周期_第21张图片

spring会调用实现了BeanPostProcessor接口的实现类的postProcessBeforeInitialization方法。

实现类包括很多(没截全)

最关键的是

  • ApplicationContextAwareProcessor 它会注入6个Aware。包括:EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware。因为只有ApplicationContext环境才能使用这些
  • InitDestroyAnnotationBeanPostProcessor 它用来调用所有注解了@PostConstrust的方法

(3)Bean初始化操作

1、调用实现了InitializingBean接口的Bean的afterPropertiesSet方法

2、调用定义bean的时候指定的init-method初始化方法

有三种方式指定初始化方法:

  1. xml方法指定   
  2. @bean方法指定 @Bean(initMethod = "初始化的方法")
  3. api的方法指定 beanDefinition.setInitMethodName(methodName);

(4)Bean初始化后操作

【spring源码分析】之bean的生命周期_第22张图片

spring会调用实现了BeanPostProcessor接口的实现类的postProcessAfterInitialization方法。

十、bean初始化完成后阶段

为了确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans

所以在全部bean初始化完成之后,spring会初始化实现了SmartInitializingSingleton接口的afterSingletonsInstantiated方法。

也包括BeanFactory自身。

带有ApplicationContext的容器,内部最终都会调用preInstantiateSingletons触发所有单例bean的初始化。

十一、Bean使用阶段

不必多说

十二、Bean销毁前阶段

bean的销毁有三种方式:

  1. AbstractAutowireCapableBean类的destoryBean方法
  2. ConfigurableBeanFactory类的destorySingletons方法
  3. ApplicationContext的close方法

Bean销毁阶段会依次执行:

  1. 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法

  2. 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法

  3. 调用bean自定义的销毁方法

spring会调用实现了DestructionAwareBeanPostProcessor接口的类的postProcessBeforeDestruction方法

【spring源码分析】之bean的生命周期_第23张图片

实现类如下:

【spring源码分析】之bean的生命周期_第24张图片

最关键的是:

  • CommonAnnotationBeanPostProcessor 它会调用bean中所有标注了@PreDestroy的方法

十三、Bean销毁阶段

自定义销毁方法有3种方式:

  1. xml中指定销毁方法
  2. @Bean中指定销毁方法  @Bean(destroyMethod = "初始化的方法")
  3. api的方式指定销毁方法 beanDefinition.setDestroyMethodName(methodName);

总结

简单bean的生命周期为:

  1. 实例化
  2. 填充属性
  3. 执行各种Aware方法(例如:beanName、beanFactory、applicationContext)
  4. 执行“预初始化”方法 BeanPostProcessor接口的beforInitlization方法
  5. 执行”初始化“方法(按顺序执行@PostConstruct 注解的方法、initializingBean的AfterPropotiesSet方法、init-method自定义初始化方法)
  6. 执行“后初始化”方法 BeanPostProcessor接口的afterInitlization方法
  7. 使用bean
  8. 执行“销毁”方法(按顺序执行 @PreDestroy注解的方法、DisposableBean接口的destoy方法、destoy-method自定义销毁方法)

【spring源码分析】之bean的生命周期_第25张图片

 

你可能感兴趣的:(spring,spring,java,后端)