Spring bean生命周期 和 三级缓存

368 阅读12分钟

参考资料

前言

平时在工作中虽然都是用的Spring框架,但是都没好好阅读过框架的代码,刚好借着周末的时间做一些学习记录加深对框架的理解。

开始学习之前先问自己几个问题:

  1. bean的生命周期是什么样的?
  2. 在bean的实例化、初始化等过程中框架调用了哪些扩展点?
  3. 什么是三级缓存,三级缓存解决了哪些问题?
  4. 为什么用三级缓存,用二级缓存实现可以吗?

本文采用的Spring源码版本是 5.2.18.RELEASE,使用的容器是基于注解配置方式的 AnnotationConfigApplicationContext

bean生命周期

基本流程

image.png

实例化bean对象

对于BeanFactory容器,当用户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器才会开始实例化bean。对于ApplicationContext容器,当容器启动时,便会实例化所有的bean。

// 容器通过AbstractAutowireCapableBeanFactory 类中的createBeanInstance方法实例化bean。
// 注意这里只是实例化bean,还没有对bean的属性进行赋值
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
   // 先解析 bean的 Class对象
   Class<?> beanClass = resolveBeanClass(mbd, beanName);

   // 如果存在实例工厂的方法,则使用该方法实例化bean
   // 检查bean是否配置了factoryMethod
   if (mbd.getFactoryMethodName() != null) {
      return instantiateUsingFactoryMethod(beanName, mbd, args);
   }

   // 如果这个bean已经被创建过了,则使用上次创建这个bean时使用的构造器进行创建
   boolean resolved = false;
   boolean autowireNecessary = false;
   if (args == null) {
      synchronized (mbd.constructorArgumentLock) {
         if (mbd.resolvedConstructorOrFactoryMethod != null) {
            resolved = true;
            autowireNecessary = mbd.constructorArgumentsResolved;
         }
      }
   }
   if (resolved) {
      if (autowireNecessary) {
         return autowireConstructor(beanName, mbd, null, null);
      }
      else {
         return instantiateBean(beanName, mbd);
      }
   }

   // 查看bean是否是SmartInstantiationAwareBeanPostProcessor接口的实例
   // 如果bean实现了determineCandidateConstructors方法,则使用该方法返回的构造器进行bean的实例化
   Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
   if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
   }

   // 获取bean默认的有参构造器
   ctors = mbd.getPreferredConstructors();
   if (ctors != null) {
      return autowireConstructor(beanName, mbd, ctors, null);
   }

   // 使用bean的无参构造器进行实例化
   return instantiateBean(beanName, mbd);
}
// beanPostProcessor对bean实例化的前置增强扩展点
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
      throws BeansException {

   if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
            if (ctors != null) {
               return ctors;
            }
         }
      }
   }
   return null;
}
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
   try {
      Object beanInstance;
      if (System.getSecurityManager() != null) {
         beanInstance = AccessController.doPrivileged(
               (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
               getAccessControlContext());
      }
      else {
          //生成bean的实例
         beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
      }
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      initBeanWrapper(bw);
      return bw;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
   }
}
// 在SimpleInstantiationStrategy类中的instantiate开始真正的实例化反射操作
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
   // 在Spring框架当中,为我们提供了一个机制,称为MethodOverride,我们称之为运行时方法重写
   // 如果bean没有使用MethodOverride机制,直接使用构造器创建对象就行
   if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
      synchronized (bd.constructorArgumentLock) {
         constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
         if (constructorToUse == null) {
            final Class<?> clazz = bd.getBeanClass();
            if (clazz.isInterface()) {
               throw new BeanInstantiationException(clazz, "Specified class is an interface");
            }
            try {
               if (System.getSecurityManager() != null) {
                  constructorToUse = AccessController.doPrivileged(
                        (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
               }
               else {
                  constructorToUse = clazz.getDeclaredConstructor();
               }
               bd.resolvedConstructorOrFactoryMethod = constructorToUse;
            }
            catch (Throwable ex) {
               throw new BeanInstantiationException(clazz, "No default constructor found", ex);
            }
         }
      }
      // 利用构造器反射实例化bean
      return BeanUtils.instantiateClass(constructorToUse);
   }
   else {
      // 如果bean使用了MethodOverride机制,则通过CGLIB去生成代理子类
      return instantiateWithMethodInjection(bd, beanName, owner);
   }
}
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
   Assert.notNull(ctor, "Constructor must not be null");
   try {
      ReflectionUtils.makeAccessible(ctor);
      if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
         return KotlinDelegate.instantiateClass(ctor, args);
      }
      else {
         Class<?>[] parameterTypes = ctor.getParameterTypes();
         Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
         Object[] argsWithDefaultValues = new Object[args.length];
         for (int i = 0 ; i < args.length; i++) {
            if (args[i] == null) {
               Class<?> parameterType = parameterTypes[i];
               // 给有参构造函数添加默认值
               argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
            }
            else {
               argsWithDefaultValues[i] = args[i];
            }
         }
         // 进行反射
         return ctor.newInstance(argsWithDefaultValues);
      }
   }
   catch (InstantiationException ex) {
       ...
   }
}

bean对象的属性赋值

// 容器通过AbstractAutowireCapableBeanFactory类中的populateBean方法填充属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   ....
   // 让实现了InstantiationAwareBeanPostProcessor接口的bean 在属性赋值之前有机会修改 bean的状态
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               return;
            }
         }
      }
   }

   PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

   int resolvedAutowireMode = mbd.getResolvedAutowireMode();
   // 检查当前自动装配的方式是否为 AUTOWIRE_BY_NAME,AUTOWIRE_BY_TYPE
   // 在xml配置的容器中,总共有5种 自动装配的方式
   // 1. no: 不进行自动装配,手动设置Bean的依赖关系(以注解方式配置的容器的默认自动装配类型)
   // 2. byName:根据Bean的名字进行自动装配
   // 3. byType:根据Bean的类型进行自动装配
   // 4. constructor:类似于byType,不过是应用于构造器的参数,如果正好有一个Bean与构造器的参数类型相同则可以自动装配,否则会导致错误
   // 5. autodetect:如果有默认的构造器,则通过constructor的方式进行自动装配,否则使用byType的方式进行自动装配。
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // 按照bean的名字进行自动装配
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
      // 按照bean的类型进行自动装配
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

   PropertyDescriptor[] filteredPds = null;
   // 如果存在 InstantiationAwareBeanPostProcessor,则执行所有InstantiationAwareBeanPostProcessor#postProcessProperties辅助完成属性填充,例如@Autowired和@Resource 等属性注入的注解就在这里被被执行
   if (hasInstAwareBpps) {
      if (pvs == null) {
         pvs = mbd.getPropertyValues();
      }
      
      // 容器会提前注入以下两个bean
      // 1. AutowiredAnnotationBeanPostProcessor,用于处理@Autowired、@Value属性注入
      // 2. CommonAnnotationBeanPostProcessor,用于处理@Resource、@PostConstruct等常用注解
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
               if (filteredPds == null) {
                  filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
               }
               pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvsToUse == null) {
                  return;
               }
            }
            pvs = pvsToUse;
         }
      }
   }
   // 进行依赖校验
   if (needsDepCheck) {
      if (filteredPds == null) {
         filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
   }
   
   if (pvs != null) {
      // 这里会对xml形式配置的容器进行属性绑定
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

初始化

// 容器通过AbstractAutowireCapableBeanFactory类中的initializeBean方法 进行初始化
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      // 检查Aware相关的接口,并根据Aware接口的类型设置依赖
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 调用BeanPostProcess前置扩展点
      // 这里会调用 InitDestroyAnnotationBeanPostProcessor类的postProcessBeforeInitialization方法
      // 在这个方法里会进行 @PostConstruct 和 @PreDestroy 注解的注入
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 开始执行初始化方法
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      // 调用BeanPostProcess后置扩展点;
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

检查Aware相关的接口,并根据Aware接口的类型设置依赖

private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof BeanNameAware) {
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

开始执行初始化方法

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {
   boolean isInitializingBean = (bean instanceof InitializingBean);
   // bean 实现了 InitializingBean 接口,如果实现了先调用 afterPropertiesSet
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         // 如果bean配置了initMethod的属性,那么调用initMethod属性指定的方法
         // 类似 @Bean(initMethod="test") 这种形式配置
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

从上面的代码中我们可以知道有三种bean初始化的方式

  • 使用@PostConstruct注解
  • 实现InitializingBean接口
  • 配置bean的initMethod属性

三种方式的执行顺序: @PostConstruct > 实现InitializingBean接口 > 配置bean的initMethod属性

注册DisposableBean到缓存中

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
   AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
   // 如果bean配置了destoryMethod属性
   // 或者容器中注册了实现了 DestructionAwareBeanPostProcessor 接口的bean
   // 就会在缓存中注册回调接口
   if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
      if (mbd.isSingleton()) {
         registerDisposableBean(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
      else {
         // 如果bean设置了一个自定义的scope
         // 自定义的score要实现 org.springframework.beans.factory.config.Scope 接口
         // 自定义的score通过 org.springframework.beans.factory.config.CustomScopeConfigurer 注册到容器中
         Scope scope = this.scopes.get(mbd.getScope());
         if (scope == null) {
            throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
         }
         // 调用自定义scope接口实现的 registerDestructionCallback方法
         scope.registerDestructionCallback(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
   }
}

Spring内置的scope

范围描述
singleton每个 Spring 容器一个实例(默认值)
prototype允许 bean 可以被多次实例化(使用一次就创建一个实例)
request定义 bean 的 scope 是 HTTP 请求。每个 HTTP 请求都有自己的实例。只有在使用有 Web 能力的 Spring 上下文时才有效
session定义 bean 的 scope 是 HTTP 会话。只有在使用有 Web 能力的 Spring ApplicationContext 才有效
application定义了每个 ServletContext 一个实例
websocket定义了每个 WebSocket 一个实例。只有在使用有 Web 能力的 Spring ApplicationContext 才有效

三级缓存

什么是三级缓存?

三级缓存听起来很高大上,其实它就是容器里的三个Map

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
   ....
   
   // 一级缓存:用于存放完全初始化好的 bean
   private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

   // 二级缓存:存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
   private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

   // 三级缓存:存放创建bean的工厂对象,用于创建bean的代理对象
   private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
   
   ....
}

三级缓存主要解决什么问题?

三级缓存主要解决bean的循环依赖

什么是循环依赖?

public class A {
    @Autowired
    private B b;
}

public class B {
    @Autowired
    private A a;
}

如上代码所示,在A里面注入B,B里面又注入A,就是循环依赖

三级缓存是如何解决循环依赖的?

利用上面的例子,假设容器现在要获取A的bean,那么流程如下:
AbstractBeanFactory获取A类bean的流程 AbstractBeanFactory获取bean的流程.png

从上面的流程我们可以看出,获取A的bean的流程类似于一个递归,既然是递归就必然存在递归的终止条件。在ioc容器中为了避免递归无法中止的情况,提供的方案就是,采用三个缓存map,在创建A的bean的过程中,会将A的bean单例工厂添加到三级缓存map中。当容器开始为A的bean填充属性B的时候,会先去获取B的bean开始新一轮的递归。当容器开始为B的bean填充属性A的时候,会再去容器中获取A的bean,然后再次开始新一轮的递归,此时容器不会再次创建A的bean,而是会从三级缓存中获取到A的bean单例工厂,然后通过bean单例工厂获取到A的bean,然后中止递归,避免死循环。

通过上面的流程我们就能够顺便知道以下几个问题的答案

  • Spring 为什么不能解决构造器注入引起的循环依赖?

通过上面的流程我们可以知道,当容器实例化bean之前,还没有将bean单例工厂对象添加到三级缓存中,当循环依赖发生时,容器无法从三级缓存中获取到bean单例工厂对象,所以会开始新一轮的递归去获取bean,并且因为三级缓存始终拿不到bean单例工厂对象,该递归无法中止。

  • Spring为什么不能解非单例bean的循环依赖?

容器只会将单例bean存Spring 为什么不能解非单例bean的循环依赖放到三级缓存中,由于非单例bean无法提前缓存,而在容器中循环依赖的解决正是通过缓存来实现的,所以Spring不能解非单例bean的循环依赖。

  • 当构造器注入出现了循环依赖,该如何解决呢?

对于构造器注入产生的循环依赖,可以使用@Lazy注解进行延迟加载。

  • 当非单例bean出现了循环依赖,该如何解决呢?

这时候就要从业务角度出发思考程序设计的是否合理,看能否把非单例bean改为单例。

为什么解决循环依赖需要三级缓存,采用两级缓存不能够解决吗?

使用两级缓存也能够解决循环依赖,但是当bean需要创建代理对象时,Spring就需要提前将代理对象创建好,这违背了Spring框架先创建bean对象,再创建代理对象的流程,并且增加了代码的复杂性。
以下是容器创建代理对象的源码,可以知道为什么采用三级缓存可以降低创建代理对象的代码复杂性。
代码1

// 我们还是用上面容器获取A类的bean来做例子
// 并且假设A类需要创建代理
// 容器在AbstractAutowireCapableBeanFactory.doCreateBean方法中创建 A类的bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      // 先实例化A类的bean
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   
   .....
   
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      // 在A类的bean实例化以后,会将A类的bean单例工厂对象提前缓存到三级缓存中
      // 也就是把一个回调方法添加到三级缓存中,回调方法的实现具体见代码2
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   Object exposedObject = bean;
   try {
      // 这里会填充A类bean的属性B
      // 在给类A的bean填充属性B的过程中,属性B又依赖于属性A,此时容器就会从三级缓存获取到A类的bean单例工厂,因为A类需要创建代理,所以该单例工厂会返回A类的代理bean,并将该代理bean添加到二级缓存中,具体实现见代码3
      populateBean(beanName, mbd, instanceWrapper);
      // 这里会初始化A类的bean
      // 在初始化的同时会调用BeanPostProcessor的后置扩展点创建A类bean的代理,具体见代码4
      exposedObject = initializeBean(beanName, exposedObject, mbd);
      
   }
   catch (Throwable ex) {
       .....
   }

   if (earlySingletonExposure) {
      // 因为类A创建了代理bean,所以需要从二级缓存中获取到类A的代理bean,并将该代理bean返回给容器
      // 确保返回的bean和注入到其他类中的bean是同一个
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         
         .....
         
      }
   }

   .....
   
   return exposedObject;
}

代码2

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
   Object exposedObject = bean;
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
            SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
            // 容器会提前注册好AbstractAutoProxyCreator类
            // 这里会通过AbstractAutoProxyCreator类给A类的bean创建代理
            exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
         }
      }
   }
   return exposedObject;
}

代码3

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
         synchronized (this.singletonObjects) {
            // Consistent creation of early reference within full singleton lock
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               singletonObject = this.earlySingletonObjects.get(beanName);
               if (singletonObject == null) {
                  // 从三级缓存中拿出用于创建bean的beanFactory对象
                  // 对应于AbstractBeanFactory获取A类bean流程的第9步
                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                  if (singletonFactory != null) {
                     // 这里就会创建bean的代理对象,并将该代理对象放在二级缓存中
                     // 对应于AbstractBeanFactory获取A类bean流程的第10步
                     singletonObject = singletonFactory.getObject();
                     this.earlySingletonObjects.put(beanName, singletonObject);
                     this.singletonFactories.remove(beanName);
                  }
               }
            }
         }
      }
   }
   return singletonObject;
}

代码4

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd {
   ....
   if (mbd == null || !mbd.isSynthetic()) {
      // 这里会调用BeanPostProcessor的后置扩展点
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      // 容器中会提前注册好 AbstractAutoProxyCreator对象,用于创建bean的代理对象
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;

从上面的代码中我们可以知道,有两个时机会给bean创建代理

  1. 当容器中出现循环依赖的bean,此时会调用三级缓存中的bean单例工厂,利用该单例工厂获取到bean的代理,然后再将bean的代理注册到二级缓存中,见代码3
  2. 在初始化bean的过程中,会调用AbstractAutoProxyCreator的getEarlyBeanReference扩展点,返回bean的代理,见代码2

所以三级缓存的意义就是延迟代理对象的创建,通过三级缓存的作用,容器不需要提前判断该bean是否需要创建代理并对其做一些特殊处理,只需要增加一个用来专门给bean创建代理的BeanPostProcessor,降低了代码的耦合度。