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

相关推荐
用户298698530142 小时前
Word 文档字符级格式化:Java 实现方案详解
java·后端
笨鸟飞不快2 小时前
从单个服务到集群:一次完整的性能排查复盘
java·前端
荣码2 小时前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
SamDeepThinking2 小时前
Java微服务练习方式
java·后端·微服务
朦胧之13 小时前
AI 编程-老项目改造篇
java·前端·后端
程序猿大帅17 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
程序员晓琪18 小时前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly18 小时前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨19 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++
东坡白菜19 小时前
破局全栈:前端开发的Java入门实战记录—JPA(2)
java·后端