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

相关推荐
Sylvia33.3 分钟前
足球数据API接入实战:从认证到实时比分推送的完整指南
java·开发语言·前端·c++·python
Chloeis Syntax8 分钟前
JavaEE初阶学习日记(1)---线程和进程
java·开发语言·学习·线程·javaee
YOU OU19 分钟前
SpringBoot
java·spring boot·spring
北冥有鱼19 分钟前
解决DTO泛滥的问题
java·java ee
国强_dev22 分钟前
如何提升canal吞吐量
java·大数据·python
时空自由民.22 分钟前
C/C++ volatile关键字原理及应用介绍
java·c语言·c++
Henray202424 分钟前
三个线程交替打印ABC
java·面试
凯瑟琳.奥古斯特25 分钟前
SpringBoot快速入门指南
java·开发语言·spring boot·后端·spring
是席木木啊31 分钟前
Tomcat CVE-2026-34483安全漏洞警告问题总结与修复方案
java·tomcat·firefox
代码漫谈33 分钟前
基于 Spring Boot 3.2.x 的 Actuator 监控指南:从健康检查到企业级监控体系
java·spring boot·actuator 监控