spring之MergedBeanDefinition探究

前言

之前读spring源码,以为Bean定义保存在beanFactory的beanDefinitionMap中,创建时获取bean定义,根据定义创建bean,简单明了


beanDefinitionMap

而最近调试发现,mergedBeanDefinitions中也存储了一份bean定义,而且创建时实际是从这个map中获取


mergedBeanDefinitions

于是对mergedBeanDefinition(合并bean定义)产生了好奇,决定看一看到底什么是合并bean定义

先说结论:
mergedBeanDefinition是为了实现bean定义继承,但感觉有点鸡肋,xml配置可以通过parent来实现,注解方式基本不再支持bean定义的继承了

所以说这篇文章也只是简单记录一下,免得mergedBeanDefinition总是干扰源码的阅读

BeanDefinition的继承

bean定义就是bean的图纸,可以配置一些属性,比如是否懒加载,是否单例等

假如现在有了A的bean定义,而B的bean定义和A的属性基本差不多,只是个别不属性太一样,那就可以让B继承A,这样可以减轻B的定义配置,就类似JAVA的继承

xml

早起都用XML配置bean定义,可以类似使用如下配置完成bean定义的继承

<bean id="A" class="com.xxx.A" lazy-init="true"></bean>
<bean id="B" class="com.xxx.B" parent="A"/> // 指定parent属性继承

实际上好像比这个复杂,但没啥意义不研究了

这样A配置了懒加载,B没有配置,就会继承懒加载的属性

这种情况下

  • (B) beanDefinitionMap存放原本的B的bean定义,而mergedBeanDefinitions存储的B是B与A合并之后的新bean
    定义
  • (A) beanDefinitionMap存放原本的A的bean定义,而mergedBeanDefinitions存储的是原本A bean定义的clone

示意图如下


A&B

这样不管存不存在合并,mergedBeanDefinitions存放的都是最终创建bean所参考的bean定义

注解

现在都不怎么用XML,都是用注解扫描自动生成bean,我大概看了一下好像没有parent相关的注解,猜测可能是这个功能太鸡肋,注解方式不提供了

而注解扫描出来的bean定义,就和上面的A一样,由于没有parent,所以在mergedBeanDefinitions只是存了份clone(如果不是RootBeanDefinition转化为RootBeanDefinition,和clone差不多)

相关代码

getMergedBeanDefinition1

getMergedBeanDefinition2

其中合并bean定义方法即为overrideFrom
overrideFrom

总结

MergedBeanDefinition的研究只是为了扫清阅读源码障碍,实际作用不大

我测试了一下,我们一个开发一年左右的代码,运行并没有进入overrideFrom方法,也就是说不光我们写的代码没用bean定义继承,第三方依赖工具也没有

私以为spring还保留着MergedBeanDefinition只是为了兼容原xml配置bean(可能也有其使用场景我不知道),而它的主要功能已经不是合并bean定义,而是把不同类型的bean定义转换为RootBeanDefinition,字面上理解为合并也可以

总之,bean定义在DefaultListableBeanFactory(springboot的beanFactory)会存储两份,一般mergedBeanDefinitions存储的是beanDefinitionMap的clone或者转换为RootBeanDefinition,实际创建bean参考的是mergedBeanDefinitions中的RootBean定义

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容