Spring IoC容器初始化

Spring IoC容器的初始化,主要分为三段

  1. 启动容器,扫描指定包路径下的Bean,封装BeanDefinition

    启动容器的三种方式:ClassPathXmlApplicationContext、AnnotationConfigApplicationContext、FileSystemXmlApplicationContext; 分别会走不同的扫描方式,最终完成BeanDefinition的封装。

  2. 装配BeanFactory

  3. 根据SpringBean的生命周期中定义的创建流程,创建Bean对象。无论以哪一种方式启动容器,最终都会交由AbstractApplicationContext类执行refresh方法进行Bean对象的创建

循环依赖

在Spring容器的初始化过程中,绕不开2个及以上Bean对象的相互依赖问题,Spring称之为循环依赖(circular references)

三级缓存

Spring对于循环依赖问题,提供了使用三级缓存的解决策略。分别为

  • singletonFactories:三级缓存,存放的是ObjectFactory,注意此处存放的不是bean对象,而是生成bean对象的factory对象。
  • earlySingletonObjects:二级缓存,存放的是由三级缓存中ObjectFactory对象执行getObject方法生成的代理对象,完成Spring通过动态代理的方式,对bean中的方法实现增强。此时该代理对象尚未开始属性注入。
  • singletonObjects:一级缓存,即最终Spring容器中的单例池,存放最终完成所有属性注入的完整bean对象。

值得注意的是:Spring在初始化Bean的过程中,并不能预先确认该Bean是否存在循环依赖的情况。因此所有Bean对象(无论有无循环依赖),在被实例化之后,属性注入之前,都会被放入三级缓存singletonFactories中,走相同的初始化流程。

初始化Bean处理AutoWired.png

为什么要使用三级缓存

看了一些关于三级缓存的博客,大部分都有描述这个问题。简单回答:需要遵守设计的“单一原则”,各级缓存各司其职。

这又衍生出另一个问题:第三级缓存的存在,到底在设计上有何优雅或者必要之处?

实际上这个三级缓存中的ObjectFactory会在Bean对象第一次属性依赖(注意不一定是循环依赖的情况)注入时,就执行它的getObject方法,获取增强后的代理对象,放入二级缓存中;此后,在每一次循环依赖属性注入时,都会从二级缓存中取得代理对象进行注入。也就是说,如果根本就没有三级缓存,直接执行掉ObjectFactory.getObject方法里的操作,获取代理对象后放入二级缓存中。理论上也是可以的,这样似乎三级缓存就没必要了?不用怀疑ObjectFactory.getObject里的操作的执行时机问题,里面只是一些纯粹的增强。

下图是源码追踪Spring解决循环依赖问题的时序图,也是Spring Bean初始化与属性注入的大致流程:

Spring Bean循环依赖.png

以下源码分析的过程,对不关注的代码进行了删减

通过ClassPathXmlApplicationContext启动容器:

public ClassPathXmlApplicationContext(
            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
            throws BeansException {

        super(parent);
        // sy 扫描配置文件,封装BeanDefinition对象 -- 所有的启动方式在构造函数中,都会先走配置扫描,做BeanDefinition封装。
        //      之后统一走AbstractApplicationContext:refresh();进行容器初始化
        // ClassPathXmlApplicationContext:setConfigLocations(configLocations);
        // FileSystemXmlApplicationContext:setConfigLocations(configLocations);
        // AnnotationConfigApplicationContext(Class<?>... componentClasses):register(componentClasses);
        // AnnotationConfigApplicationContext(String... basePackages):scan(basePackages);
        // -- AbstractApplicationContext:refresh();
        setConfigLocations(configLocations);
        if (refresh) {
            // sy 初始化IoC容器
            refresh();
        }
    }

ClassPathXmlApplicationContext的构造函数最终走AbstractApplicationContext.refresh方法,完成BeanFactory与Bean的建立

AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            // sy 获取BeanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            // sy 预装配BeanFactory
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                // sy 模板方法
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                // sy 设置工程中实现的BeanFactoryPostProcessors并执行postProcessBeanFactory方法
                // 最终通过DefaultListableBeanFactory.doGetBeanNamesForType遍历beanDefinitionNames获取BeanFactoryPostProcessors。
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
                // sy 注册BeanPostProcessors
                // 调用时机:Bean实例化 -> Bean对象属性注入 -> BeanNameAware.setBeanName -> BeanFactoryAware.setBeanFactory -> ApplicationContextAware.setApplicationContext
                //          -> **** BeanPostProcessor.postProcessBeforeInitialization ****
                //              -> InitializingBean.afterPropertiesSet -> 调用xml定制的init-method方法或者Bean中用@PostConstruct注解的方法
                //          -> **** BeanPostProcessor.postProcessAfterInitialization  ****
                //              -> Singleton:放入单例池中,由Spring容器管理; Prototype:交给调用者,由JVM管理
                registerBeanPostProcessors(beanFactory);

                // Initialize message source for this context.
                // sy 国际化
                initMessageSource();

                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // Check for listener beans and register them.
                registerListeners();

                // Instantiate all remaining (non-lazy-init) singletons.
                // sy 最终完成IoC注入的调用
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

执行AbstractApplicationContext#finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化Bean
        beanFactory.preInstantiateSingletons();
    }

执行DefaultListableBeanFactory#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
        if (logger.isTraceEnabled()) {
            logger.trace("Pre-instantiating singletons in " + this);
        }

        // Iterate over a copy to allow for init methods which in turn register new bean definitions.
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        // Trigger initialization of all non-lazy singleton beans...
        // sy 通过遍历封装完毕的BeanDefinition,逐一创建Spring Bean
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    // sy 处理FactoryBean
                    //  从容器中获取FactoryBean时,使用"&"+beanName的原因
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            // sy 初始化bean
                            getBean(beanName);
                        }
                    }
                }
                else {
                    // sy 初始化bean
                    getBean(beanName);
                }
            }
        }

        // Trigger post-initialization callback for all applicable beans...
        for (String beanName : beanNames) {
            // 逐一从一级缓存、二级缓存、三级缓存中获取实例化对象
            Object singletonInstance = getSingleton(beanName);
            // 对单例bean对象的后置增强
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

执行AbstractBeanFactory#getBean -> 调用内部AbstractBeanFactory#doGetBean方法

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        final String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        // sy 依次从一级缓存、二级缓存、三级缓存中获取bean对象
        Object sharedInstance = getSingleton(beanName);
        // sy 如果已获得bean且其无参构造
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            // sy 处理factoryBean的情况
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // sy 如果当前的bean的scope为prototype,则抛出异常,prototype类型的bean不应该在初始化阶段生成
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // sy 根据得到的BeanFactory做getBean递归
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
            }

            try {
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        registerDependentBean(dep, beanName);
                        try {
                            // sy 递归创建依赖对象
                            getBean(dep);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                    // sy 看命名应该能明白,该方法最终返回了一个singleton的bean对象,即存放在singletonObjects(一级缓存单例池中的对象)
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // sy 最终创建bean代理对象的地方
                            return createBean(beanName, mbd, args);
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
            }
        }
    
        return (T) bean;
    }

如果能使用DefaultListableBeanFactory#preInstantiateSingletons.getSingleton方法从缓存中得到bean,则之前已走过实例化流程。该方法很关键:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        Object singletonObject = this.singletonObjects.get(beanName);
        // sy 如果对象不在单例池singletonObjects(一级缓存)中
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                // sy 如果对象不在二级缓存earlySingletonObjects中
                if (singletonObject == null && allowEarlyReference) {
                    // sy 从三级缓存singletonFactories中获取中获取ObjectFactory
                    //      注意三级缓存singletonFactories中存放的是ObjectFactory,并不是bean对象,即此时没有生成bean的代理对象
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // sy 通过匿名内部类实现ObjectFactory接口的getObject,创建Bean对象
                        //      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
                        singletonObject = singletonFactory.getObject();
                        // sy 将生成的Bean对象放入二级缓存中
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        // sy 从一级缓存中移除使用beanName标记的ObjectFactory
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

如果从缓存中获取不到bean,说明该Bean对象尚未进行实例化,走org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton方法:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   synchronized (this.singletonObjects) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            // sy 执行beanFactory的getObject方法即:
            //        () -> {
            //                try {
            //                   // sy 最终创建bean代理对象的地方(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean)
            //                   return createBean(beanName, mbd, args);
            //                }
            //                catch (BeansException ex) {
            //                   // Explicitly remove instance from singleton cache: It might have been put there
            //                   // eagerly by the creation process, to allow for circular reference resolution.
            //                   // Also remove any beans that received a temporary reference to the bean.
            //                   destroySingleton(beanName);
            //                   throw ex;
            //                }
            //             }
            //    创建最终完成增强的完整的singleton代理对象
            //    并在下方执行addSingleton(beanName, singletonObject),将其放进单例缓存池中,并将其从三级、二级缓存中删除
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         finally {
            if (recordSuppressedExceptions) {
               this.suppressedExceptions = null;
            }
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            // sy 将初始化完成的bean对象放入单例池中
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

由singletonObject = singletonFactory.getObject()执行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean方法:这里删除了异常处理的代码,主要关注2个方法:resolveBeforeInstantiation、doCreateBean(最终创建Bean对象)

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        RootBeanDefinition mbdToUse = mbd;

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // sy 听名字有点疑惑,
            //  设置BeanPostProcessors的postProcessBeforeInitialization,postProcessAfterInitialization。
            //  这样似乎说明会在Bean依赖注入完毕就立马执行BeanPostProcessor ?
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }

        try {
            // sy 创建bean对象
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        }
    }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean这个方法做了3件事:

  • addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
    

    将ObjectFactory加入三级缓存中

  • populateBean(beanName, mbd, instanceWrapper)
    

    进行属性注入

  • exposedObject = initializeBean(beanName, exposedObject, mbd)
    

    在bean装配完成后,执行BeanPostProcessor与init-method

源码详解:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      // sy factoryBeanInstanceCache.put前会将beanName做一步createBeanInstance
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   // sy 如果为空说明当前尚未创建过Bean对象
   if (instanceWrapper == null) {
      // sy 最终都会走createBeanInstance方法去实例化对象,仅仅只是实例化原生对象,尚未对bean对象进行属性注入,也未生成代理对象且增强
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         mbd.postProcessed = true;
      }
   }
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      // sy 在bean实例化之后,将其BeanFactory:() -> getEarlyBeanReference(beanName, mbd, bean)放入三级缓存中,
      //        可解决循环依赖问题(默认开启允许循环依赖:this.allowCircularReferences的默认值为true)
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      // sy 为bean对象执行属性注入。
      populateBean(beanName, mbd, instanceWrapper);
      // sy 在bean装配完成后,执行BeanPostProcessor与init-method
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }

   // sy 如果在二级缓存中
   if (earlySingletonExposure) {
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
         }
      }
   }

   // Register bean as disposable.
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }

   return exposedObject;
}

重点关注属性装配:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  
   // 前面做了一系列处理去获取pvs:propertyValues
   if (pvs != null) {
      // sy 解决@AutoWired注入
      applyPropertyValues(beanName, mbd, bw, pvs);
   }
}

最终调用了org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyPropertyValues:

这里面主要做了2件事

  • Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    

    通过调用BeanDefinitionValueResolver.resolveValueIfNecessary获取该属性的值

  • bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    

    通过BeanWrapper.setPropertyValues方法将获取的属性值,注入到属性对象中。内部使用了PropertyAccessor(属性存取器)做了一些处理,最终在org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue方法中使用反射进行属性值注入:

    public void setValue(final @Nullable Object value) throws Exception {
       final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
             ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
             this.pd.getWriteMethod());
       if (System.getSecurityManager() != null) {
          AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
             ReflectionUtils.makeAccessible(writeMethod);
             return null;
          });
          try {
             AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                   writeMethod.invoke(getWrappedInstance(), value), acc);
          }
          catch (PrivilegedActionException ex) {
             throw ex.getException();
          }
       }
       else {
          // sy 暴力调用
          ReflectionUtils.makeAccessible(writeMethod);
          writeMethod.invoke(getWrappedInstance(), value);
       }
    }
    

最终该方法的源码详情:

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // Create a deep copy, resolving any references for values.
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        for (PropertyValue pv : original) {
            if (pv.isConverted()) {
                deepCopy.add(pv);
            }
            else {
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                // sy 处理property的注入值
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                }
            }
        }

        // Set our (possibly massaged) deep copy.
        try {
            // sy 将获取的属性值,通过反射注入到属性对象中
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
    }

进入org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary方法:

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
   // 这方法其实东西挺多的,处理的情况也比较多。大部分直接会走第一个if条件,就不看其他的了
   if (value instanceof RuntimeBeanReference) {
      RuntimeBeanReference ref = (RuntimeBeanReference) value;
      // sy 处理引用(即对象引用)
      return resolveReference(argName, ref);
   }
}

进入org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference方法:

这个方法很关键,是下一轮递归的入口:

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
   try {
      Object bean;
      String refName = ref.getBeanName();
      refName = String.valueOf(doEvaluate(refName));
      if (ref.isToParent()) {
         bean = this.beanFactory.getParentBeanFactory().getBean(refName);
      }
      else {
         // sy 很熟悉吧。又回到了最初的getBean,算是一种递归吧。
         //     递归结束的条件即在getBean方法中从三级到一级缓存内获取到了bean对象。此时该bean对象即增强后的代理对象了。
         //       如果在缓存内未取得bean对象,则继续向下递归,若取得,则向上回归
         bean = this.beanFactory.getBean(refName);
         this.beanFactory.registerDependentBean(refName, this.beanName);
      }
      return bean;
   }
}

最终在最后一层递归完成,向上回归到第一次getBean方法内的getSingleton方法中,从一级缓存(单例池)中获取完整对象后,实例化完成。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351

推荐阅读更多精彩内容