Spring生命周期 2 合并beandefinion

Spring生命周期 2 合并beandefinion

合并bean定义的作用 其实就是如果一个父bean设置的一些属性,子bean可以继承比如。

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClass(father.class);
rootBeanDefinition.getPropertyValues().add("age",18);
applicationContext.registerBeanDefinition("father",rootBeanDefinition);

GenericBeanDefinition g = new GenericBeanDefinition();
g.setParentName("root");
applicationContext.registerBeanDefinition("child",g);
applicationContext.refresh();
System.out.println(applicationContext.getBean(son.class).getAge());

可以看到 child并没有设置值,然后输出的年龄有值。

子bean继承父bean源码

	/**
覆盖此bean定义(想必是从父子继承关系中复制的父级)
	 中给定bean定义(想必是子级)的设置。<ul> <li>将覆盖在给定bean定义中指定的beanClass。
	 <li>总是从给定的bean定义中获取{@code abstract}、{@code scope}、{@code lazyInit}、
	 {@code autowireMode}、{@code dependencyCheck}和{@code dependsOn}。
	 <li>将从给定的bean定义中添加{@code constructorArgumentValues}, {@code propertyValues},
	 {@code methodOverrides}到现有的bean定义中。<li>将覆盖{@code factoryBeanName}, {@code factoryMethodName},
	 {@code initMethodName}和{@code destroyMethodName},如果在给定的bean定义中指定的话。
	 * </ul>
	 */
public void overrideFrom(BeanDefinition other) {
   if (StringUtils.hasLength(other.getBeanClassName())) {
      setBeanClassName(other.getBeanClassName());
   }
   if (StringUtils.hasLength(other.getScope())) {
      setScope(other.getScope());
   }
   setAbstract(other.isAbstract());
   if (StringUtils.hasLength(other.getFactoryBeanName())) {
      setFactoryBeanName(other.getFactoryBeanName());
   }
   if (StringUtils.hasLength(other.getFactoryMethodName())) {
      setFactoryMethodName(other.getFactoryMethodName());
   }
   setRole(other.getRole());
   setSource(other.getSource());
   copyAttributesFrom(other);

   if (other instanceof AbstractBeanDefinition) {
      AbstractBeanDefinition otherAbd = (AbstractBeanDefinition) other;
      if (otherAbd.hasBeanClass()) {
         setBeanClass(otherAbd.getBeanClass());
      }
      if (otherAbd.hasConstructorArgumentValues()) {
         getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
      }
      if (otherAbd.hasPropertyValues()) {
         getPropertyValues().addPropertyValues(other.getPropertyValues());
      }
      if (otherAbd.hasMethodOverrides()) {
         getMethodOverrides().addOverrides(otherAbd.getMethodOverrides());
      }
      Boolean lazyInit = otherAbd.getLazyInit();
      if (lazyInit != null) {
         setLazyInit(lazyInit);
      }
      setAutowireMode(otherAbd.getAutowireMode());
      setDependencyCheck(otherAbd.getDependencyCheck());
      setDependsOn(otherAbd.getDependsOn());
      setAutowireCandidate(otherAbd.isAutowireCandidate());
      setPrimary(otherAbd.isPrimary());
      copyQualifiersFrom(otherAbd);
      setInstanceSupplier(otherAbd.getInstanceSupplier());
      setNonPublicAccessAllowed(otherAbd.isNonPublicAccessAllowed());
      setLenientConstructorResolution(otherAbd.isLenientConstructorResolution());
      if (otherAbd.getInitMethodName() != null) {
         setInitMethodName(otherAbd.getInitMethodName());
         setEnforceInitMethod(otherAbd.isEnforceInitMethod());
      }
      if (otherAbd.getDestroyMethodName() != null) {
         setDestroyMethodName(otherAbd.getDestroyMethodName());
         setEnforceDestroyMethod(otherAbd.isEnforceDestroyMethod());
      }
      setSynthetic(otherAbd.isSynthetic());
      setResource(otherAbd.getResource());
   }
   else {
      getConstructorArgumentValues().addArgumentValues(other.getConstructorArgumentValues());
      getPropertyValues().addPropertyValues(other.getPropertyValues());
      setLazyInit(other.isLazyInit());
      setResourceDescription(other.getResourceDescription());
   }
}

从头开始看----getbean方法中找到最开始一行,也就是先获取合并的bean定义。

合并bean在refresh方法中的

// 实例化非懒加载的单例Bean
beanFactory.preInstantiateSingletons();

一直找调用方法 一直到org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition(java.lang.String, org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.config.BeanDefinition)这个方法中。

mergedBeanDefinitions这个是用来存储合并bean定义的map

protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

   synchronized (this.mergedBeanDefinitions) {
      RootBeanDefinition mbd = null;
      RootBeanDefinition previous = null;

      // 现在使用全锁检查,以强制执行相同的合并实例。
      if (containingBd == null) {
         mbd = this.mergedBeanDefinitions.get(beanName);
      }
//mbd.stale确定定义是否需要重新合并
      if (mbd == null || mbd.stale) {
         previous = mbd;
          //bd.getParentName()等于空说明他是父类
         if (bd.getParentName() == null) {
            // Use copy of given root bean definition.
            if (bd instanceof RootBeanDefinition) {
               mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            } else {
               mbd = new RootBeanDefinition(bd);
            }
         } else {
            // Child bean definition: needs to be merged with parent.
            // pbd表示parentBeanDefinition
            BeanDefinition pbd;
            try {
                //转化bean的父名称,
               String parentBeanName = transformedBeanName(bd.getParentName());
               if (!beanName.equals(parentBeanName)) {
                  pbd = getMergedBeanDefinition(parentBeanName);
               } else {
                  BeanFactory parent = getParentBeanFactory();
                  if (parent instanceof ConfigurableBeanFactory) {
                     pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                  } else {
                     throw new NoSuchBeanDefinitionException(parentBeanName,
                           "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                 "': cannot be resolved without a ConfigurableBeanFactory parent");
                  }
               }
            } catch (NoSuchBeanDefinitionException ex) {
               throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                     "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
            }

            // Deep copy with overridden values.
            // 子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并
            mbd = new RootBeanDefinition(pbd);
             //把对应关系映射上
            mbd.overrideFrom(bd);
         }

         // Set default singleton scope, if not configured before.
         if (!StringUtils.hasLength(mbd.getScope())) {
            mbd.setScope(SCOPE_SINGLETON);
         }

         // A bean contained in a non-singleton bean cannot be a singleton itself.
         // Let's correct this on the fly here, since this might be the result of
         // parent-child merging for the outer bean, in which case the original inner bean
         // definition will not have inherited the merged outer bean's singleton status.
         if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
            mbd.setScope(containingBd.getScope());
         }

         // Cache the merged bean definition for the time being
         // (it might still get re-merged later on in order to pick up metadata changes)
         if (containingBd == null && isCacheBeanMetadata()) {
            this.mergedBeanDefinitions.put(beanName, mbd);
         }
      }
      if (previous != null) {
         copyRelevantMergedBeanDefinitionCaches(previous, mbd);
      }
      return mbd;
   }
}

合并bean定义源码完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值