BeanDefinition体系架构(待...)

AbstractBeanDefinition 仅仅只有三个直接的子类,分别是:RootBeanDefinitionChildBeanDefinitionGenericBeanDefinition

注:在 Spring2.5 之前,仅仅只有 RootBeanDefinition、ChildBeanDefinition 两个子类,

我们一般通过 RootBeanDefinition 来定义一个 Bean 对象,但是有时候会出现这么一种情况:

java 复制代码
RootBeanDefinition bd1 = new RootBeanDefinition();
bd1.setBeanClassName( "com.test1" );
bd1.setScope( BeanDefinition.SCOPE_SINGLETON );
....
    
RootBeanDefinition bd2 = new RootBeanDefinition();
bd2.setBeanClassName( "com.test2" );
bd2.setScope( BeanDefinition.SCOPE_SINGLETON );
....
    
RootBeanDefinition bd3 = new RootBeanDefinition();
bd3.setBeanClassName( "com.test3" );
bd3.setScope( BeanDefinition.SCOPE_SINGLETON );
....

由上述定义可以看到,这些 BeanDefinition 会有相同的设置(setScope( "singleton" )),从而造成冗余,于是 Spring 就使用了一种 伪继承 模式:

我们可以将多个 BeanDefinition 的公共部分放置在一个 RootBeanDefinition 中,然后创建多个 ChildBeandefinition,并且指定 parent 为 RootBeanDefinition 即可,如下:

java 复制代码
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setScope( BeanDefinition.SCOPE_SINGLETON );
rootBeanDefinition.setLazyInit( false );
rootBeanDefinition.setAbstract( true ); // 设置为抽象的, 则在创建bean对象的时候不会被创建
context.registerBeanDefinition( "root", rootBeanDefinition );

ChildBeanDefinition childBeanDefinition1 = new ChildBeanDefinition( "root" ); // 指定parent为"root"
childBeanDefinition1.setBeanClass( TestClass1.class );
context.registerBeanDefinition( "child1", childBeanDefinition1 );

ChildBeanDefinition childBeanDefinition2 = new ChildBeanDefinition( "root" ); // 指定parent为"root"
childBeanDefinition2.setBeanClass( TestClass2.class );
context.registerBeanDefinition( "child2", childBeanDefinition2 );

通过上述的方式,就可以将一些公共的设置给抽离出来了,从而使得 RootBeanDefinition 既可以独立成 一个 bean 定义,也可以作为多个 bean 定义的父类,

而 ChildBeanDefinition 则可以指定 parent 为 root 来共享公共的定义

在 Spring2.5 以后,Spring 又定义了一个 GenericBeanDefinition,从而打破了原来 RootBeanDefinition 以及 ChildBeanDefinition 的弊端(替代 ChildBeanDefinition):

ChildBeanDefinition 在创建时必须指定 parent,而 RootBeanDefinition 又不能有 parent(它的 setParentName() 方法会抛出异常)

即 GenericBeanDefinition 比 ChildBeanDefinition、RootBeanDefinition 更加灵活,既可以单独作为 BeanDefinition,也可以作为父 BeanDefinition,还可以作为子 BeanDefinition。所以 GenericBeanDefinition 也称为 "通用的 BeanDefinition"

我们在使用 Spring 的时候可以知道,在一个 Bean 对象是可以定义一些注解的,比如我们可以自定义一个 @Hello 注解,那么一个 GenericBeanDefinition 是没法存储下这些注解的信息的,

于是为了能够存储注解信息,GenericBeanDefinition 又衍生出了两个子类,分别是:AnnotatedGenericBeanDefinition、ScannedGenericBeanDefinition,

参考博客:https://juejin.cn/post/6844904167933231117

相关推荐
伊玛目的门徒4 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
懒鸟一枚7 小时前
深入理解 Linux 内存、Swap 交换分区与分页机制的关系
java·linux·数据库
我命由我123458 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
考虑考虑8 小时前
Sentinel安装
java·后端·微服务
凤凰院凶涛QAQ10 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
掘金_答案11 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构
猿与禅11 小时前
CosId 分布式 ID 生成器完全教程:从架构原理到生产落地
java·shardingsphere·雪花算法·分布式id·高性能·cosid·号段模式
MindUp11 小时前
企业网盘权限模型解析:多层级访问控制与审计能力选型指南
java·linux·运维
NG47711 小时前
【软件设计与体系结构】-策略设计模式
java·设计模式·软件工程
程序员天天困12 小时前
优雅记录操作日志:从注解到 SpEL 的全链路实践与开源方案对比
java·后端