Spring IOC学习(5)——AbstractAutowireCapableBeanFactory

目录

 

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

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

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

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

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


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

Spring IOC学习(5)——AbstractAutowireCapableBeanFactory

/**
  * 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对象为例梳理一下过程

Spring IOC学习(5)——AbstractAutowireCapableBeanFactory

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

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);
 }

 

上一篇:Spring源码分析系列——bean创建过程分析(二)——有参构造方法创建bean


下一篇:Spring容器 —— 深入 bean 的加载(五、初始化 bean)