深入理解Spring IOC(六)、 bean的填充以及初始化工作(上)

简介: 深入理解Spring IOC(六)、 bean的填充以及初始化工作(上)

如果你已经看到了这里并且把之前的都看明白了,那么恭喜你,最难的地方你已经搞定了。现在在整个spring ioc的流程中,对你来说应该不会再有太难的了,同时再去看spring的其他模块的源码,也相对会容易一些,尤其是其他框架和Spring整合的代码。如果没有看懂的也别着急,你可以把本篇看完,然后回过头去再去看之前的,源码也很少有人一遍就能看明白,我自己看这块的源码也是看了很多遍以及debug了很多遍才明白的。

!

复制代码

真的需要你的一个赞来鼓励一下,因为写这种源码解析真的太太太太不容易了😢,谁写谁知道。

回到正题,我们上一篇主要说了doCreateBean中的createBeaninstance这个方法,这个方法为我们创建了未被填充的bean实例,本篇我们来看已经创建出来的bean实例是怎样被填充以及初始化的。

我们回到doCreateBean方法中,我再把这个方法代码贴一下,其中,1处上篇已经讲过,我们直接来看第2处

typescript

复制代码

代码块1
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
  // BeanWrapper是bean的包装类
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
    // 从正在创建的factoryBean的缓存中移除(准确说其实是去拿,同时移除)
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  if (instanceWrapper == null) {
    // 1. 如果到这里是null,则去创建一个包含着bean实例的instanceWrapper
    instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
  Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
  // 使用MergedBeanDefinitionPostProcessor修改RootBeanDefinition
  // 主要是处理@Autowired 、 @inject 、@value 标着的方法和属性
  // 从这里往后,spring 才知道是哪个方法或者是属性有这个注解
  // 这里的具体的代码解析不再贴出来(因为不是重点),在我第一篇的github上面你也可以自己下载源码来看,里面都有注释
  synchronized (mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
      applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      mbd.postProcessed = true;
    }
  }
  // earlySingletonExposure是判断是否要提前曝光这个半成品的实例的,注意哈:现在的bean只是个半成品
  // 因为还没有进行属性填充,以及执行初始化方法等操作
  // mbd是单例 && 允许循环引用(默认true) && 当前bean是不是正在创建中
  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");
    }
    // 提前曝光这个beanName对应的ObjectFactory,用来解决循环引用
    addSingletonFactory(beanName, new ObjectFactory<Object>() {
      @Override
      public Object getObject() throws BeansException {
        // 2.使用SmartInstantiationAwareBeanPostProcessor返回早期bean的半成品时的引用
        // 如果没有SmartInstantiationAwareBeanPostProcessor,则直接返回bean
        // 这里返回的最终是bean本身
        return getEarlyBeanReference(beanName, mbd, bean);
      }
    });
  }
  // 初始化
  Object exposedObject = bean;
  try {
    // 3. 对bean进行属性填充
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
      // 4. 初始化操作
      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);
    }
  }
  // 如果需要提前曝光半成品bean
  if (earlySingletonExposure) {
    Object earlySingletonReference = getSingleton(beanName, false);
    if (earlySingletonReference != null) {
      if (exposedObject == bean) {
        // 由于经过init之后的操作,earlySingletonReference和exposedObject可能不是一个实例,
        // 这里需要让他们指向一个实例,
        exposedObject = earlySingletonReference;
      // 不允许在循环依赖情况下注入原始bean && 当前bean被其他bean依赖
      }else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
        // 拿到当前bean依赖所有bean的数组
        String[] dependentBeans = getDependentBeans(beanName);
        Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
        for (String dependentBean : dependentBeans) {
          // 移除这些bean,因为这些bean依赖的bean是被增强过的bean
          if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
            // 移除失败的添加到actualDependentBeans
            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.");
        }
      }
    }
  }
  try {
    // 注册用于销毁的bean,
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }catch (BeanDefinitionValidationException ex) {
    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }
  return exposedObject;
}

代码块1中2处


代码块2
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
  Object exposedObject = bean;
  // bean不是null && mbd不是合成 && 有InstantiationAwareBeanPostProcessor
  if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    // 遍历执行BeanPostProcessor
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
        // 具体的处理逻辑位于AutowiredAnnotationBeanPostProcessor中,它继承了这个方法,最终返回的还是是bean本身,
        // 注意:如果有别的实现了SmartInstantiationAwareBeanPostProcessor就未必了
        exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
        if (exposedObject == null) {
          return exposedObject;
        }
      }
    }
  }
  return exposedObject;
}


此时我相信这里你肯定是可以看明白的


代码块1中3处


这个populateBean方法,即是处理属性注入的地方,@Autowired,@Resource,@Value,甚至是当你使用Dubbo框架的时候@Reference都是在这里处理注入的,我们一起看看这个方法:


代码块3
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
  PropertyValues pvs = mbd.getPropertyValues();
  // 进行基本的校验,bw为null时
  if (bw == null) {
    // 如果有属性值,则抛异常
    if (!pvs.isEmpty()) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
    // 否则 结束方法
    }else {
      return;
    }
  }
  // 是否继续填充属性的标记
  boolean continueWithPropertyPopulation = true;
  // mbd是否为合成 && 是否存在InstantiationAwareBeanPostProcessor
  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
        // postProcessAfterInstantiation这个方法是在bean实例化后属性填充之前调用
        // 返回的是true,说明应该进行属性填充,false说明不应该
        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
          continueWithPropertyPopulation = false;
          break;
        }
      }
    }
  }
  // 如果不该继续填充了则直接返回
  if (!continueWithPropertyPopulation) {
    return;
  }
  // 这个是处理xml中autowire的值为byname 和 byType的逻辑
  // 可以看出来只有xml的才会走这里,注解的没有byName 和 byType这样的属性
  if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
      mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    // 1.byName的处理
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
      autowireByName(beanName, mbd, bw, newPvs);
    }
    // 2.byType的处理
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      autowireByType(beanName, mbd, bw, newPvs);
    }
    pvs = newPvs;
  }
  // 是否有InstantiationAwareBeanPostProcessors
  boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  // 是否需要依赖检查
  boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
  if (hasInstAwareBpps || needsDepCheck) {
    PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    if (hasInstAwareBpps) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
          // 用InstantiationAwareBeanPostProcessor的后置处理来进行属性的填充
          // 这里进行的是属性填充前最后一步的处理,@AutoWired就是在这里进行处理的
          // 也就是说这里会对@Autowired的属性进行初始化,然后加到pvs中来
          // 当然,@Resource也是在这里处理的,只是用的BeanPostProcessor不是一个
          // 注:@Autowired的处理逻辑在AutowiredAnnotationBeanPostProcessor中,而
          // @Resource的在CommonAnnotationBeanPostProcessor里
          InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
          pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
          if (pvs == null) {
            return;
          }
        }
      }
    }
    if (needsDepCheck) {
      // 对filteredPds里面的属性进行依赖检查
      checkDependencies(beanName, mbd, filteredPds, pvs);
    }
  }
  // 3.进行填充操作
  applyPropertyValues(beanName, mbd, bw, pvs);
}


这个代码块中的1、2个,是针对xml中bean标签的autowire属性的,虽然现在用的很少了,但是本着完整的原则,还是来看看它:


代码块3中1处


代码块4
protected void autowireByName(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
  // 获取需要注入的属性的名称
  String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
  for (String propertyName : propertyNames) {
    // 如果现在beanFactory容器中有这个propertyName对应的bean或者是
    // 对应的beanDefinition
    if (containsBean(propertyName)) {
      // 则去初始化这个bean
      Object bean = getBean(propertyName);
      // 将所依赖的bean加入pvs容器中以备后续使用
      pvs.add(propertyName, bean);
      // 注册依赖关系
      registerDependentBean(propertyName, beanName);
      if (logger.isDebugEnabled()) {
        logger.debug("Added autowiring by name from bean name '" + beanName +
            "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
      }
    }
    else {
      if (logger.isTraceEnabled()) {
        logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
            "' by name: no matching bean found");
      }
    }
  }
}


代码块3中2处


代码块5
protected void autowireByType(
      String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
  // 拿自定义的TypeConverter,如果为空,则用bw做TypeConverter
  TypeConverter converter = getCustomTypeConverter();
  if (converter == null) {
    converter = bw;
  }
  Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
  // 拿到需要注入的属性的名称
  String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
  for (String propertyName : propertyNames) {
    try {
      // 拿到bw的对应这个propertyName的PropertyDescriptor
      PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
      // 如果pd是个Object类型的,则不注入这个。原因是如果是Object,你找到的参数即使类型不匹配
      // 也能注入成功。。
      if (!Object.class.equals(pd.getPropertyType())) {
        MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
        // Do not allow eager init for type matching in case of a prioritized post-processor.
        boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
        DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
        // 真正的解析过程
        Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
        // 把解析成功的参数放到pvs里
        if (autowiredArgument != null) {
          pvs.add(propertyName, autowiredArgument);
        }
        for (String autowiredBeanName : autowiredBeanNames) {
          registerDependentBean(autowiredBeanName, beanName);
          if (logger.isDebugEnabled()) {
            logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
                propertyName + "' to bean named '" + autowiredBeanName + "'");
          }
        }
        autowiredBeanNames.clear();
      }
    }
    catch (BeansException ex) {
      throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
    }
  }
}



目录
相关文章
|
6天前
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
15 2
|
6天前
|
XML Java 数据格式
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
17 3
|
1天前
|
运维 Java 关系型数据库
Spring运维之boot项目bean属性的绑定读取与校验
Spring运维之boot项目bean属性的绑定读取与校验
10 2
|
4天前
|
存储 Java 测试技术
Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
6 1
|
6天前
|
Java 开发者 Spring
Spring 中 Bean 的生命周期
Spring 中 Bean 的生命周期
11 2
|
5天前
|
Java Spring
在Spring Boot中,可以通过控制`@PostConstruct`注解方法的执行顺序来实现初始化时的顺序控制
在Spring Boot中,可以通过控制`@PostConstruct`注解方法的执行顺序来实现初始化时的顺序控制
18 1
|
1月前
|
XML Java 数据格式
④【Spring】IOC - 基于注解方式 管理bean
④【Spring】IOC - 基于注解方式 管理bean
54 0
|
1月前
|
XML Java 数据格式
②【Spring】一文精通:IOC - 基于XML方式管理Bean
②【Spring】一文精通:IOC - 基于XML方式管理Bean
150 0
|
1月前
|
Java Spring 容器
Spring核心概念、IoC和DI的认识、Spring中bean的配置及实例化、bean的生命周期
Spring核心概念、IoC和DI的认识、Spring中bean的配置及实例化、bean的生命周期
41 0
|
1月前
|
XML Java 数据格式
掌握 Spring IoC 容器与 Bean 作用域:详解 singleton 与 prototype 的使用与配置
在您的应用程序中,由 Spring IoC 容器管理的形成其核心的对象被称为 "bean"。一个 bean 是由 Spring IoC 容器实例化、组装和管理的对象
56 0