BeanDefinition 合并

举报
JavaEdge 发表于 2021/06/03 23:23:01 2021/06/03
【摘要】   BeanDefinition 的合并 1.BeanDefinition 有父子关系,有个属性叫parentName,通过parentName可以设置BeanDefinition的父子关系2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像3.BeanDefinition 的合并过程就是将父子关系...

 

BeanDefinition 的合并

  • 1.BeanDefinition 有父子关系,有个属性叫parentName,通过parentName可以设置BeanDefinition的父子关系
  • 2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像
  • 3.BeanDefinition 的合并过程就是将父子关系的 BeanDefinition 属性合并起来,如果有相同的就使用子类的属性值 例子:
    
              AnnotationConfigApplicationContext applicationContext
             = new AnnotationConfigApplicationContext(springConfiguration.class);
             //父 RootBeanDefinition 
             RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
             rootBeanDefinition.setScope(AbstractBeanDefinition.SCOPE_DEFAULT);
             rootBeanDefinition.getPropertyValues().add("name","xiaoming");
             applicationContext.registerBeanDefinition("parent",rootBeanDefinition);
              //子 ChildBeanDefinition ,会继承使用父类已有的属性值,但是如果属性值冲突,不一样
              //那么合并过程中就会使用子类的
             ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("parent");
             childBeanDefinition.setBeanClass(A.class);
             childBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
            复制代码
        
       

    什么时候做合并

    在初始化bean工厂的过程中调用: PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors->DefaultListableBeanFactory.getBeanNamesForType
  • DefaultListableBeanFactory.getBeanNamesForType

      public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
      //....... 
      return doGetBeanNamesForType
      //......
       }
      复制代码
  
 
  • DefaultListableBeanFactory#doGetBeanNamesForType

      private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
       List<String> result = new ArrayList<>();
      // 遍历所有的 beanDefinitionNames
      for (String beanName : this.beanDefinitionNames) {
      // Only consider bean as eligible if the bean name
      // is not defined as alias for some other bean.
      if (!isAlias(beanName)) {
      try {
      //获取合并的bd
       RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
      //.....
       }
      复制代码
  
 
  • AbstractBeanFactory#getMergedLocalBeanDefinition

      protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
      // 先尝试从缓存获取bd(就是一个map)
       RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
      if (mbd != null) {
      return mbd;
       }
      //合并bd
      return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
       }
      复制代码
  
 
  • AbstractBeanFactory#getMergedBeanDefinition

    
            protected RootBeanDefinition getMergedBeanDefinition(
             String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {
            synchronized (this.mergedBeanDefinitions) {
             RootBeanDefinition mbd = null;
            // 先从缓存拿合并的bd
            if (containingBd == null) {
             mbd = this.mergedBeanDefinitions.get(beanName);
             }
            //合并的bd为空就进行bd合并
            if (mbd == null) {
            //如果父类为空,就不进行bd合并
            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 {
            // 进行bd合并
             BeanDefinition pbd;
            try {
             String parentBeanName = transformedBeanName(bd.getParentName());
            if (!beanName.equals(parentBeanName)) {
            //父类的bd可能也需要合并,所以调用 getMergedBeanDefinition
             pbd = getMergedBeanDefinition(parentBeanName);
             }
            else {
             BeanFactory parent = getParentBeanFactory();
            if (parent instanceof ConfigurableBeanFactory) {
             pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
             }
             }
             }
            //进行bd合并,子类覆盖父类的,如果子类没有,就用父类的属性
             mbd = new RootBeanDefinition(pbd);
             mbd.overrideFrom(bd);
             }
            // Set default singleton scope, if not configured before.
            if (!StringUtils.hasLength(mbd.getScope())) {
             mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
             }
             }
            return mbd;
             }
            }
            复制代码
        
       

 

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/108177864

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。