BeanDefinition 合并

BeanDefinition 的合并

  • 1.BeanDefinition 有父子关系,有个属性叫parentName,通过parentName可以设置BeanDefinition的父子关系

  • 2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像

  • 3.BeanDefinition 的合并过程就是将父子关系的 BeanDefinition 属性合并起来,如果有相同的就使用子类的属性值 例子:

    1 AnnotationConfigApplicationContext applicationContext 2 = new AnnotationConfigApplicationContext(springConfiguration.class); 3 //父 RootBeanDefinition 4 RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); 5 rootBeanDefinition.setScope(AbstractBeanDefinition.SCOPE_DEFAULT); 6 rootBeanDefinition.getPropertyValues().add("name","xiaoming"); 7 applicationContext.registerBeanDefinition("parent",rootBeanDefinition); 8 9 //子 ChildBeanDefinition ,会继承使用父类已有的属性值,但是如果属性值冲突,不一样 10 //那么合并过程中就会使用子类的 11 ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("parent"); 12 childBeanDefinition.setBeanClass(A.class); 13 childBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME); 14 15复制代码

    什么时候做合并

    在初始化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<>();

    1 // 遍历所有的 beanDefinitionNames 2 for (String beanName : this.beanDefinitionNames) { 3 // Only consider bean as eligible if the bean name 4 // is not defined as alias for some other bean. 5 if (!isAlias(beanName)) { 6 try { 7 //获取合并的bd 8 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 9 //..... 10}

    复制代码

  • AbstractBeanFactory#getMergedLocalBeanDefinition

    1protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { 2 // 先尝试从缓存获取bd(就是一个map) 3 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); 4 if (mbd != null) { 5 return mbd; 6 } 7 //合并bd 8 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 9}

    复制代码

  • AbstractBeanFactory#getMergedBeanDefinition

    1protected RootBeanDefinition getMergedBeanDefinition( 2 String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 3 throws BeanDefinitionStoreException { 4 5 synchronized (this.mergedBeanDefinitions) { 6 RootBeanDefinition mbd = null; 7 8 // 先从缓存拿合并的bd 9 if (containingBd == null) { 10 mbd = this.mergedBeanDefinitions.get(beanName); 11 } 12 //合并的bd为空就进行bd合并 13 if (mbd == null) { 14 //如果父类为空,就不进行bd合并 15 if (bd.getParentName() == null) { 16 // Use copy of given root bean definition. 17 if (bd instanceof RootBeanDefinition) { 18 mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); 19 } 20 else { 21 mbd = new RootBeanDefinition(bd); 22 } 23 } 24 else { 25 // 进行bd合并 26 BeanDefinition pbd; 27 try { 28 String parentBeanName = transformedBeanName(bd.getParentName()); 29 if (!beanName.equals(parentBeanName)) { 30 //父类的bd可能也需要合并,所以调用 getMergedBeanDefinition 31 pbd = getMergedBeanDefinition(parentBeanName); 32 } 33 else { 34 BeanFactory parent = getParentBeanFactory(); 35 if (parent instanceof ConfigurableBeanFactory) { 36 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); 37 } 38 } 39 } 40 //进行bd合并,子类覆盖父类的,如果子类没有,就用父类的属性 41 mbd = new RootBeanDefinition(pbd); 42 mbd.overrideFrom(bd); 43 } 44 45 // Set default singleton scope, if not configured before. 46 if (!StringUtils.hasLength(mbd.getScope())) { 47 mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); 48 } 49 } 50 51 return mbd; 52 } 53} 54 55复制代码
点赞
收藏

评论区

加载中...

相关推荐

一篇文章带你搞懂Python中的继承和多态

一、继承的介绍继承是一种创建新的类的方式,新创建的叫子类,继承的叫父类、超类、基类。继承的特点就是子类可以使用父类的属性(特征、技能)。继承是类与类之间的关系。继承可以减少代码冗余、提高重用性。在现实生活中,继承一般指的是子女继承父辈的财产,如下图:二、如何用继承?1.继承语法Class派生类名(基类名):基类名写在括号里。在继承关系中,已有的,设计好

spring源码解析

前言上篇我们介绍了spring容器加载的方式,并重点介绍了基于xml配置解析和注解扫描两种容器加载的方式,封装和注册beandefinition的过程。今天我们分享BeanDefinition注册后的另一个重要过程bean的实例化过程的源码。容器加载流程!spring源码解析spring容器加载源码(bean实

Python的新式类和旧式类

概述:Python中支持多继承,也就是一个子类可以继承多个父类/基类。当一个调用一个自身没有定义的属性时,它是按照何种顺序去父类中寻找的呢?尤其是当众多父类中都包含有同名的属性,这就涉及到新式类和经典类的区别。多继承:classFood(object):23def__init__(self,name,col

Python Day24:类的继承、派生、覆盖、super()、绑定、非绑定方法

类的继承、派生、覆盖、super()python类的继承:子类继承父类,只需要在定义类的时候在类名后面加上(父类名)。继承之后,父类的属性方法、子类都可以访问派生:子类继承父类后,自己在父类的基础上,又添加了一些属于自己特性的属性、方法

Java的类继承

知识点1、继承作用:提高代码的重用性,继承之后子类可以继承父类中的属性和方法减少重复代码条件:子类和父类要满足isa的逻辑关系,才能使用继承。如:苹果isa水果语法:使用extends连接子类和父类。子类extends父类Java是单继承,一个类只能继承一个父类。子类不能继承父类私有的属性,但是可以

Java面试题(一)

看到一篇不错的java面试题的文章,自己整理一下,作为备用吧!Java面试题面向对象的特征有哪些方面?封装最常见的是把属性私有化封装在一个类里面,只能通过方法去访问继承子类继承父类,从而继承了父类的方法和属性抽象