Spring中,Bean生产销毁过程代表一个Bean的生命周期。
image.png
Bean创建的生命周期
xx.class—>无参构造方法(存在多个时,spring会自己推断使用构造方法)—>实例化前—>实例化普通对象—>实例化后—>依赖注入(即:属性赋值)—>初始化前(@PostConstruct)—>初始化(InitializingBean)—>初始化后(AOP)—>代理对象—>Bean对象(如果进行AOP处理,此处是代理对象)

实例化前、后,都是使用InstantiationAwareBeanPostProcessors三个方法(BeanPostProcess的子接口)
1.前:可以自定义实例过程(postProcessBeforeInstantiation方法完成)
2.后:(postProcessAfterInstantiation方法完成)
属性注入
3.spring默认属性注入,(byName使用set方法名、byType根据参数类型)
4.@Autowrite方式属性注入操作:(postProcessProperties方法完成)

初始化前、后,都是使用BeanPostProcess接口完成

BeanPostProcess
IOC初始化扫描阶段,识别BeanPostProcess类型实现类,并实例化,将实例化的BeanPostProcess暂存到List中
在普通类初始化前、后,循环调用,对普通类进行额外操作

AOP代理对象
生产代理类—>代理对象—>代理对象target属性赋值(target=普通对象)

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
AOP就是利用BeanProcessor上面方法进行实现的,在postProcessAfterInitialization方法中生成代理对象,并返回

标记那些对象需要进行AOP代理
切面bean(使用@Aspect @Component注解标记),也是一个bean。
在扫描阶段会被遍历,获取所有被切面标记的bean,并进行缓存。在这些被标记的bean初始化后阶段,对这些Bean进行AOP操作。
AOP操作完成后,代理对象会被缓存,后续使用时,使用代理对象。

BeanFactoryPostProcessor、BeanProcessor、Aware接口实现原理
都是在Spring执行过程中,通过判断对象类型(通过instanceof关键字),然后类型强转,进行调用接口方法

前言

利用Spring管理实例Bean,首先从单例池中获取Bean。

  1. 获取到,直接返回。
  2. 获取不到,开始Bean生成过程。在执行完初始化后,添加到单例池中。

    一、Bean生成过程

    1.生成BeanDefinition

    Spring启动时,调用org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan扫描指定包路径,得到BeanDefinition集合,最终存放到:
    beanDefinitionMap:存放原始的BeanDefinition
    beanDefinitionNames:存放已经注册的类名。实例化时,用于递归生成实例对象
    image.png
    扫描阶段会创建BeanPostProcesser类型bean,并使用List缓存。处理普通Bean的初始化(前后)逻辑,循环调用所有BeanPostProcessor。

加载过程

类扫描流程
CachingMetadataReaderFactory解析某个.class文件得到MetadataReader对象是利用的ASM技术,类并没有加载到JVM。最终得到的ScannedGenericBeanDefinition对象。
其中beanClass属性存储的是当前类的名字,而不是class对象。(beanClass属性的类型是Object,它即可以存储类的名字,也可以存储class对象。在加载类步骤中,被赋值为class对象)

获取BeanDefinition方式

除了,通过扫描得到BeanDefinition对象。还可以通过直接定义BeanDefinition,或解析spring.xml文件的,或者@Bean注解得到BeanDefinition对象。

MetadataReader元数据读取器

主要包含了一个AnnotationMetadata属性,功能有

  1. 1. 获取类的名字、
  2. 2. 获取父类的名字
  3. 3. 获取所实现的所有接口名
  4. 4. 获取所有内部类的名字
  5. 5. 判断是不是抽象类
  6. 6. 判断是不是接口
  7. 7. 判断是不是一个注解
  8. 8. 获取拥有某个注解的方法集合
  9. 9. 获取类上添加的所有注解信息
  10. 10. 获取类上添加的所有注解类型集合

2.合并BeanDefinition

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
image.png
通过扫描得到所有BeanDefinition之后,因为Spring中支持父子BeanDefinition合并操作,执行完合并操作,就可以根据BeanDefinition创建Bean对象。
在Spring中支持父子BeanDefinition合并操作,会重新生成一个BeanDefinition(RootBeanDefinition),而不是选择一个修改。
mergedBeanDefinitions:存放合并后的BeanDefinition,用于实例化对象。

合并步骤

  1. 1. 检查是否完成合并。(在mergedBeanDefinitions尝试获取)
  2. 2. 根据BeanName,从beanDefinitionMap中,获取当前容器的BeanDefinition
  3. 3. 检查BeanDefinition.getParentName属性,判断是否存在BeanDefinition继承关系。存在则进行属性合并。
  4. 4. 使用beanDefinitionMapBeanDefinition,对新生成的RootBeanDefinition相同属性进行覆盖。

3.加载类

org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass
image.png
合并完成后,依次加载当前BeanDefinition对应的class(前期使用ASM技术,并未真正加载class),进行实例化操作。
加载之前,BeanDefinition的beanClass属性,存储的还是字符串。加载完成后,beanClass属性被重新赋值为Class对象。

ClassUtils.getDefaultClassLoader()

  1. 优先返回当前线程中的ClassLoader
  2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
  3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器

    4.实例化前

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
    目前Spring容器,持有的对象是Class对象。实例化过程:是将Class对象变成实例Bean
    在此(实例化之前)阶段,可以利用InstantiationAwareBeanPostProcessor进行实例化前控制。如果postProcessBeforeInstantiation方法返回结果,则不会继续后续实例化动作(例如:属性注入、初始化),直接执行初始化后逻辑(一般用于支持AOP逻辑处理)。【与factoryBean类似】
    image.png

源码分析

  1. //【实例化前】动作。
  2. //如果存在实例化前扩展,且有返回值。则直接继续执行【初始化后扩展】
  3. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  4. Object bean = null;
  5. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  6. // Make sure bean class is actually resolved at this point.
  7. //是否存在实例化前操作接口(InstantiationAwareBeanPostProcessor,实例化前调用,可用自己的实例化过程代替spring的过程)
  8. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  9. Class<?> targetType = determineTargetType(beanName, mbd);
  10. if (targetType != null) {
  11. //执行实例化前动作
  12. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  13. if (bean != null) {
  14. //**执行了实例化前扩展后,直接直接初始化后扩展点。(一般用于AOP逻辑处理)**/
  15. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  16. }
  17. }
  18. }
  19. mbd.beforeInstantiationResolved = (bean != null);
  20. }
  21. return bean;
  22. }
  23. //【实例化前】动作。
  24. //如果存在实例化前扩展,且有多个返回值,只会返回一个。
  25. @Nullable
  26. protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  27. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  28. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  29. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  30. Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
  31. //如果多个实现,仅需要一个有返回值
  32. if (result != null) {
  33. return result;
  34. }
  35. }
  36. }
  37. return null;
  38. }

5.实例化

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
根据BeanDefinition创建实例。

singletonObject:一级缓存池
earlySingletonObject:二级缓存池
singletonFactories:三级缓存池
完成步骤12(初始化),实例bean才会加入单例池中
image.png

5.1.Supplier调用

首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。
作用,目前没搞清楚,感觉是利用JDK函数式接口,增加的一个扩展

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {//判断BeanDefinition中是否设置了Supplier
return obtainFromSupplier(instanceSupplier, beanName);
}

protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;

String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(beanName);
try {
instance = instanceSupplier.get();//调用Supplier的get()得到对象
} finally {
if (outerBean != null) {
this.currentlyCreatedBean.set(outerBean);
} else {
this.currentlyCreatedBean.remove();
}
}

if (instance == null) {
instance = new NullBean();
}
BeanWrapper bw = new BeanWrapperImpl(instance);
initBeanWrapper(bw);
return bw;
}

5.2.工厂方法调用

若没有设置Supplier,则检查BeanDefin ition中是否设置了factoryMethod,也就是工厂方法,有两种方式可以设置factoryMethod。
@Bean所定义的BeanDefinition,也支持factoryMethod和factoryBean的
使用示例

5.3.推断构造方法

1.选择构造方法以及查找入参对象。
2.判断在对应的类中是否存在使用@Lookup注解的方法。
如果存在则把该方法封装为LookupOverride对象并添加到BeanDefinition中。
3.在实例化时,
如果当前BeanDefinition中没有LookupOverride,则直接用构造方法反射得到实例对象。
如果存在LookupOverride对象,即存在@Lookup注解了的方法,则会生成一个代理对象

5.4.SmartInitializingSingleton

当所有非懒加载Bean实例化完成后。会循环判断实例对象是否实现SmartInitializingSingleton。如果实现则执行afterSingletonsInstantiated

  1. //1.完成所有非懒加载bean实例化后。2.递归单例池对象,判断是否实现SmartInitializingSingleton接口。
  2. for (String beanName : beanNames) {
  3. //从单例池中获取实例
  4. Object singletonInstance = getSingleton(beanName);
  5. //实例化完成后,判断实例化的bean是否实现了SmartInitializingSingleton
  6. // 可以作为InitializingBean的替代方案,它在 bean 的本地构造阶段结束时被触发
  7. if (singletonInstance instanceof SmartInitializingSingleton) {
  8. final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
  9. if (System.getSecurityManager() != null) {
  10. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  11. smartSingleton.afterSingletonsInstantiated();
  12. return null;
  13. }, getAccessControlContext());
  14. }
  15. else {
  16. //【【所有非懒加载bean实例化完成后,进行调用】】
  17. smartSingleton.afterSingletonsInstantiated();
  18. }
  19. }
  20. }

6.BeanDefinition后置处理

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
image.png
调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法,可以修改合并后的BeanDefinition.
例如可以调用BeanDefinition的setInitMethodName手动添加初始化方法,一般不这么干。

注入依赖准备工作

调用AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition查找注入点(@Autowired、@Value、@Inject标记的属性、方法),进行缓存,为后续属性注入做准备
调用CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition查找注入点(@Resource标记的属性与方法),进行缓存。为后续属性注入做准备

7.实例化后

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

目前Spring容器,已经完成实例化(将Class对象变成实例Bean),所以postProcessAfterInstantiation参数是实例的对象BeanName.目前实例对象的属性还没有赋值。
image.png
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation

8.属性(依赖)注入

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
执行完实例化后的逻辑后。
继续执行
1.执行Spring内部(已过期的)依赖注入逻辑。(依赖set方法。框架没有侵入性。)
2.调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法处理:@Autowired、@Resource、@Value注解。(识别注解,有一定的侵入性)
image.png
Spring通过实现InstantiationAwareBeanPostProcessor,将依赖注入组件化。如果需要扩展,只需要继续实现InstantiationAwareBeanPostProcessor即可

  1. //todo 1.根据注入点进行注入
  2. //利用 InstantiationAwareBeanPostProcessor#postProcessProperties 处理spring自动注入动作
  3. //调用AutowiredAnnotationBeanPostProcessor,对注入点(@Autowired、@Value、@Inject标记的属性、方法),进行属性注入
  4. //调用CommonAnnotationBeanPostProcessor,对注入点(@Resource标记的属性与方法),进行属性注入
  5. for (BeanPostProcessor bp : getBeanPostProcessors()) {
  6. if (bp instanceof InstantiationAwareBeanPostProcessor) {
  7. InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
  8. //【利用反射技术】进行属性注入
  9. PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  10. if (pvsToUse == null) {
  11. if (filteredPds == null) {
  12. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  13. }
  14. //过期方法
  15. pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  16. if (pvsToUse == null) {
  17. return;
  18. }
  19. }
  20. pvs = pvsToUse;
  21. }
  22. }

9.属性解析

10.执行Aware

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
完成属性赋值之后,(如果当前Bean实现了指定Aware)Spring会执行一些回调,包括:

  1. BeanNameAware:回传beanName给bean对象。
  2. BeanClassLoaderAware:回传classLoader给bean对象。
  3. BeanFactoryAware:回传beanFactory给对象。

    11.初始化前

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
    image.png

    BeanPostProcessor

  4. InitDestroyAnnotationBeanPostProcessor会在初始化前,执行@PostConstruct的方法,

  5. ApplicationContextAwareProcessor会在初始化前,执行其他Aware的回调:

    1. EnvironmentAware:回传环境变量
    2. EmbeddedValueResolverAware:回传占位符解析器
    3. ResourceLoaderAware:回传资源加载器
    4. ApplicationEventPublisherAware:回传事件发布器
    5. MessageSourceAware:回传国际化资源
    6. ApplicationStartupAware:回传应用其他监听对象,可忽略
    7. ApplicationContextAware:回传Spring容器ApplicationContext

      源码实现

      1. //循环调用BeanPostProcessor
      2. @Override
      3. public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      4. throws BeansException {
      5. Object result = existingBean;
      6. for (BeanPostProcessor processor : getBeanPostProcessors()) {
      7. Object current = processor.postProcessBeforeInitialization(result, beanName);
      8. if (current == null) {
      9. return result;
      10. }
      11. result = current;
      12. }
      13. return result;
      14. }

      12.初始化

      org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

  6. 检查当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法

  7. 执行BeanDefinition中指定的初始化方法

    13.初始化后

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
    源码与初始化前调用类似,只是调用BeanPostProcessor#postProcessAfterInitialization方法。

14.BeanPostProcessor调用

  1. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
  2. 实例化
  3. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
  4. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
  5. 自动注入
  6. InstantiationAwareBeanPostProcessor.postProcessProperties()
  7. Aware对象
  8. BeanPostProcessor.postProcessBeforeInitialization()
  9. 初始化
  10. BeanPostProcessor.postProcessAfterInitialization()

    二、Bean销毁过程

    org.springframework.beans.factory.support.AbstractBeanFactory#registerDisposableBeanIfNecessary
    SpringBean销毁,是在Spring容器正常关闭时触发。而不是垃圾回收时触发。
    非原型Bean才有销毁逻辑。因为原型Bean不会再容器中存储,不存在销毁
    Spring销毁逻辑
    1.实现DisposableBean(或AutoCloseable)接口。
    2.使用@PreDestroy注解,标记方法

    1.销毁Bean信息收集(创建Bean时完成收集)

    信息收集,发生在初始化后,并存入disposableBeans中(LinkedHashMap)
    image.png

    protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
    return (bean.getClass() != NullBean.class &&
    (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
    DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
    }

  1. 判断当前Bean是否实现DisposableBean、AutoCloseable接口、BeanDefinition中是否指定了destroyMethod。[DisposableBeanAdapter.hasDestroyMethod(bean, mbd)]
  2. 调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断[DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()]
    1. ApplicationListenerDetector中直接使得ApplicationListener是DisposableBean
    2. InitDestroyAnnotationBeanPostProcessor中使得拥有@PreDestroy注解了的方法就是DisposableBean
  3. 把符合上述任意条件的Bean,包装成DisposableBeanAdapter对象,并存入disposableBeans中(LinkedHashMap

    2.Spring容器关闭过程

    关闭容器。context.close()

    1. 首先发布ContextClosedEvent事件
    2. 调用lifecycleProcessor的onCloese()方法
    3. 销毁单例Bean
      1. 遍历disposableBeans
        1. 把每个disposableBean从单例池中移除
        2. 调用disposableBean的destroy()
        3. 如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean
        4. 如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉 (inner bean参考https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-inner-beans)
      2. 清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName
      3. 清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组
      4. 清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean