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<>();// 遍历所有的 beanDefinitionNamesfor (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 {//获取合并的bdRootBeanDefinition 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;}//合并bdreturn getMergedBeanDefinition(beanName, getBeanDefinition(beanName));}
复制代码
  • AbstractBeanFactory#getMergedBeanDefinition

    protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized (this.mergedBeanDefinitions) {RootBeanDefinition mbd = null;// 先从缓存拿合并的bdif (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可能也需要合并,所以调用 getMergedBeanDefinitionpbd = 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;}
    }复制代码

BeanDefinition 合并相关推荐

  1. Spring官网阅读(四)BeanDefinition(上)

    前面几篇文章已经学习了官网中的1.2,1.3,1.4三小结,主要是容器,Bean的实例化及Bean之间的依赖关系等.这篇文章,我们继续官网的学习,主要是BeanDefinition的相关知识,这是Sp ...

  2. spring 源码_spring源码系列(一)——spring循环引用

    众所周知spring在默认单例的情况下是支持循环引用的 为了节省图片大小我把那些可以动得gif图片做成了只循环一次,如果看到图片不动了请右键选择在新标签打开,那么图片就会动,手机用户则更简单,直接手指 ...

  3. spring生命周期七个过程_Spring杂文(三)Spring循环引用

    众所周知spring在默认单例的情况下是支持循环引用的 Appconfig.java类的代码 @Configurable @ComponentScan("com.sadow") p ...

  4. 异常将上下文初始化事件发送到类的侦听器实例_Spring的Bean实例化原理,这一次彻底搞懂了!...

    前言 之前分析了Spring XML和注解的解析原理,并将其封装为BeanDefinition对象存放到IOC容器中,而这些只是refresh方法中的其中一个步骤--obtainFreshBeanFa ...

  5. 不一样 使用别名 数据字段和bean_【修炼内功】[spring-framework] [3] Bean是如何创建又是如何销毁的?...

    书接上文,在 [spring-framework] [2] BeanDefinitionReader 一文中简单介绍了XMLBeanFactory解析xml配置.并注册BeanDefinition的逻 ...

  6. 这一次搞懂 Spring 的 Bean 实例化原理

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/l6108003/article/ details/106439525 前言 前两篇文章分析了Spring XML和注解的解析原 ...

  7. Spring源码剖析 循环注入

    版权声明:本文为CSDN博主「shadow?s」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/java_ly ...

  8. Spring源码之启动过程(四)—— Bean的实例化详解

    前面,我们把Bean的生命周期做了一个概述和梳理,为的是更深刻的理解容器启动及Bean的生命周期,最主要的是Bean的实例化过程,没有看过的,可以进去先看一下(文章链接:Spring源码之Bean的生 ...

  9. Spring源码解析(五)-Bean的实例化流程(上)

    在前面已经完成了对需要实例化bean的收集并封装成BeanDefinition,并且将BeanPostProcess等组件进行了提前实例化.接下来就到了容器启动的最后一步,也是最复杂的一步-实例化be ...

最新文章

  1. Linux echo 显示内容颜色
  2. 费用流 ZOJ 3933 Team Formation
  3. idea打断点启动项目后debug红点内没有√,导致无法调试
  4. es6遍历树结构并判断_ES6和ES5中数据结构的遍历
  5. 解题:洛谷3402 可持久化并查集
  6. ArrayAdapter requires the resource ID to be a TextView错误
  7. 【人工智能 一种现代方法】搜索-复习
  8. Proteus仿真:存储器
  9. 监控--CactiEZ使用
  10. oracle查询asm的绝对路径,查找ASM 1号文件位置
  11. CentOS7.6重装系统步骤
  12. 信号隔离器的功能原理是什么?
  13. Redis底层数据结构介绍
  14. 比 Elasticsearch 更快!RediSearch + RedisJSON = 王炸
  15. ARP攻击-流量分析
  16. 网页弹出对话框的几种代码
  17. C++PrimerPlus 第二章 开始学习C++
  18. 【1170】计算2的N次方
  19. linux文件操作常见考题_江西理工大学linux操作系统测试题(看完必过)
  20. 【移动端h5常用的几款插件 】

热门文章

  1. 操作系统第一章操纵系统引论
  2. 看完全都会了!2021届毕业生还没找到Android开发工作,含BATJM大厂
  3. 2022年初级审计师考试复习题及答案
  4. CVPR 2020 论文大盘点-行人检测与重识别篇
  5. Win系统 - 关于 CPU C-States 省电模式,你需要知道的事情
  6. 2019张小龙微信公开课精华整理(未完待续....)
  7. 常用数学符号读法及其含义
  8. D3.js音乐可视化
  9. 系统结构图、程序流程图、数据流图
  10. 用Python做了个不良图片识别系统(附源码)