ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring IOC学习(5)——AbstractAutowireCapableBeanFactory

2021-01-14 22:31:37  阅读:163  来源: 互联网

标签:Object mbd Spring beanName 对象 bean 缓存 AbstractAutowireCapableBeanFactory IOC


目录

 

AbstractAutowireCapableBeanFactory:在AbstractBeanFactory的基础上,增加了“自动依赖注入”能力

至此,循环依赖问题解决了。以A对象和B对象为例梳理一下过程

单例对象在三级缓存中的存活时期

为什么Spring选择了三级缓存而不是二级缓存

有可能生成代理对象的三个地方


AbstractAutowireCapableBeanFactory:在AbstractBeanFactory的基础上,增加了“自动依赖注入”能力

/**
  * Dependency types to ignore on dependency check and autowire, as Set of
  * Class objects: for example, String. Default is none.
  * 给新创建的bean进行依赖注入时忽略(跳过)的类型;默认没有
  */
 private final Set<Class<?>> ignoredDependencyTypes = new HashSet<Class<?>>();

 /**
  * Dependency interfaces to ignore on dependency check and autowire, as Set of
  * Class objects. By default, only the BeanFactory interface is ignored.
  * 给新创建的bean进行依赖注入时忽略(跳过)的接口;默认BeanFactory
   * 举例,A实现ApplicationContextAware接口,就可以把ApplicationContext添加到里面,依赖注入时跳过;后续再通过setApplicationContext方法完成该属性的初始化
  */
 private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<Class<?>>();

 /**
  * 这个类的关键方法:创建一个bean实例,完成属性注入,进行后置处理等
  * 也是AbstractBeanFactory的doGetBean里用到的方法
  * Central method of this class: creates a bean instance,
  * populates the bean instance, applies post-processors, etc.
  * @see #doCreateBean
  */
 @Override
 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
  if (logger.isDebugEnabled()) {
   logger.debug("Creating instance of bean '" + beanName + "'");
  }
  RootBeanDefinition mbdToUse = mbd;

  // Make sure bean class is actually resolved at this point, and
  // clone the bean definition in case of a dynamically resolved Class
  // which cannot be stored in the shared merged bean definition.
  //根据bean定义解析出class对象
  //提提AbstractBeanDefinition的beanClass属性:解析前是类,如A;解析后是类对应的class对象,如Class<A>
  Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
   //应该是确保有解析完成的class对象
   mbdToUse = new RootBeanDefinition(mbd);
   mbdToUse.setBeanClass(resolvedClass);
  }

  // Prepare method overrides.
  try {
   //检查方法重写:bean定义里记录的重写方法和beanClass的是否一致
   mbdToUse.prepareMethodOverrides();
  }
  catch (BeanDefinitionValidationException ex) {
   throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
     beanName, "Validation of method overrides failed", ex);
  }

  try {
   //给了一个扩展的机会:这里可以直接返回代理对象,而不用走后面创建对象的流程(AOP的实现相关)
   // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
   if (bean != null) {
    return bean;
   }
  }
  catch (Throwable ex) {
   throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
     "BeanPostProcessor before instantiation of bean failed", ex);
  }
  //到这里才根据bean定义创建对象
  Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  if (logger.isDebugEnabled()) {
   logger.debug("Finished creating instance of bean '" + beanName + "'");
  }
  return beanInstance;
 }

/**
  * Actually create the specified bean. Pre-creation processing has already happened
  * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
  * <p>Differentiates between default bean instantiation, use of a
  * factory method, and autowiring a constructor.
  * @param beanName the name of the bean
  * @param mbd the merged bean definition for the bean
  * @param args explicit arguments to use for constructor or factory method invocation
  * @return a new instance of the bean
  * @throws BeanCreationException if the bean could not be created
  * @see #instantiateBean
  * @see #instantiateUsingFactoryMethod
  * @see #autowireConstructor
  */
 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
   throws BeanCreationException {

  // Instantiate the bean.
  //BeanWrapper里有对应的bean,相当于工具类
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
   instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  //要创建的bean
  final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
  //bean对应的class对象
  Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
  mbd.resolvedTargetType = beanType;

  // Allow post-processors to modify the merged bean definition.
  synchronized (mbd.postProcessingLock) {
   if (!mbd.postProcessed) {
    try {
     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    }
    catch (Throwable ex) {
     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
       "Post-processing of merged bean definition failed", ex);
    }
    mbd.postProcessed = true;
   }
  }

  // Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like BeanFactoryAware.
  //这里就是解决循环依赖的地方:提前将bean对应的SingletonFactory放到三级缓存中,再次调用doGetBean就可以从缓存中取到了
  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
  if (earlySingletonExposure) {
   if (logger.isDebugEnabled()) {
    logger.debug("Eagerly caching bean '" + beanName +
      "' to allow for resolving potential circular references");
   }
   addSingletonFactory(beanName, new ObjectFactory<Object>() {
    @Override
    public Object getObject() throws BeansException {
     return getEarlyBeanReference(beanName, mbd, bean);
    }
   });
  }

  // Initialize the bean instance.
  //初始化bean
  Object exposedObject = bean;
  try {
   //填充属性、依赖注入;会对其需要注入的属性调用getBean方法
   populateBean(beanName, mbd, instanceWrapper);
   if (exposedObject != null) {
    //填充完属性之后,(如果需要则)依次执行以下回调方法:
    //1、BeanNameAware.setBeanName
    //2、BeanClassLoaderAware.setBeanClassLoader
    //3、BeanFactoryAware.setBeanFactory
    //4、BeanPostProcessor.postProcessBeforeInitialization
    //5、InitializingBean.afterPropertiesSet
    //6、InitMethod
    //7、BeanPostProcessor.postProcessAfterInitialization
    exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
  }
  catch (Throwable ex) {
   if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    throw (BeanCreationException) ex;
   }
   else {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
   }
  }

  if (earlySingletonExposure) {
   //注意第二个参数为false,所以是从一级二级缓存获取bean;此时只有三级缓存存在bean对应的factory,如果其他地方没有再次调用doGetBean,将返回null
   Object earlySingletonReference = getSingleton(beanName, false);
   if (earlySingletonReference != null) {
    //说明再次调用过doGetBean
    if (exposedObject == bean) {
     //需要获取此bean的原对象时,这句代码没影响;
     //需要获取此bean的代理对象时,更新exposedObject为代理对象
     exposedObject = earlySingletonReference;
    }
    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
     //发生了这种情况:此bean需要生成代理对象;在执行initializeBean过程中exposedObject更新为了最新的代理对象,
     //之后其他对象调用getBean,获取到了另一个代理对象(即wrapIfNecessary被调用了两次,重复生成了两个不同的代理对象)
     //抛个异常方便排错
     String[] dependentBeans = getDependentBeans(beanName);
     Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
     for (String dependentBean : dependentBeans) {
      if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
       actualDependentBeans.add(dependentBean);
      }
     }
     if (!actualDependentBeans.isEmpty()) {
      throw new BeanCurrentlyInCreationException(beanName,
        "Bean with name '" + beanName + "' has been injected into other beans [" +
        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
        "] in its raw version as part of a circular reference, but has eventually been " +
        "wrapped. This means that said other beans do not use the final version of the " +
        "bean. This is often the result of over-eager type matching - consider using " +
        "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
     }
    }
   }
  }

  // Register bean as disposable.
  //注册实现了DisposableBean接口的bean
  try {
   registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
   throw new BeanCreationException(
     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
 }

至此,循环依赖问题解决了。以A对象和B对象为例梳理一下过程

单例对象在三级缓存中的存活时期

1、实例化完成后,先进第三级缓存:singletonFactories

2、第一次调用getSingleton方法获取提前暴露的对象时,从第三级缓存转移到第二级缓存:earlySingletonObjects

3、完成属性填充、执行回调后,整个对象准备就绪;从第二级缓存转移到第一级缓存:singletonObjects

为什么Spring选择了三级缓存而不是二级缓存

两级缓存不能满足AOP场景下的需求,如果对象实例化完成后马上放入第二级缓存,其他bean只能获取到提前暴露的该bean本身,而无法获取代理对象;第三级缓存的SingletonFactory,可以获取到代理对象或原对象(视情况而定),再放入第二级缓存中

有可能生成代理对象的三个地方

1、createBean方法中,对象实例化前(暂时不理解)

2、doCreateBean方法中,对象填充属性完毕后,执行回调方法,到了AbstractAutoProxyCreator.postProcessAfterInitialization里

/**
  * Create a proxy with the configured interceptors if the bean is
  * identified as one to proxy by the subclass.
  * @see #getAdvicesAndAdvisorsForBean
  */
 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  if (bean != null) {
   //cacheKey相当于一个唯一标识
   Object cacheKey = getCacheKey(bean.getClass(), beanName);
   if (!this.earlyProxyReferences.contains(cacheKey)) {
    //如果有其他bean依赖此bean,并且已经调用过getBean方法,则不会到这里,而是直接返回原对象
    //如果需要则生成代理对象并返回,否则返回原对象
    return wrapIfNecessary(bean, beanName, cacheKey);
   }
  }
  return bean;
 }

3、其他依赖此bean的对象调用getBean方法,进入到了AbstractAutoProxyCreator.getEarlyBeanReference获取到了提前暴露的对象

public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
  Object cacheKey = getCacheKey(bean.getClass(), beanName);
  if (!this.earlyProxyReferences.contains(cacheKey)) {
   //添加进去,避免postProcessAfterInitialization方法里重复调用wrapIfNecessary
   this.earlyProxyReferences.add(cacheKey);
  }
  //如果需要则生成代理对象
  return wrapIfNecessary(bean, beanName, cacheKey);
 }

 

标签:Object,mbd,Spring,beanName,对象,bean,缓存,AbstractAutowireCapableBeanFactory,IOC
来源: https://blog.csdn.net/Rylynn_plus/article/details/112642262

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有