Spring原理学习系列之六:IOC原理之BeanDefinition注册

  • BeanDefinition

  • BeanDefinitionRegistry

  • 总结


一、BeanDefinition


纳尼,你还要说Spring IOC,之前的文章你还没有说够嘛?

在这里插入图片描述

谁让Spring中关于IOC这部分的内容这么多呢,前面的文章还没有说的很细。所以只能继续慢慢往下唠叨了。废话不多说,我们来继续IOC

BeanDefinition是用来描述Spring中的Bean,是包装Bean的数据结构。其源码如下所示:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

//标准单例作用域的作用域标识符:“singleton”,对于扩展的bean工厂可能支持更多的作用域

String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

//标准原型作用域的范围标识符:“prototype”

String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

//表示BeanDefinition是应用程序主要部分的角色提示,通常对应于用户定义的bean

int ROLE_APPLICATION = 0;

//表示BeanDefinition是某些大型配置的支持部分的角色提示,通常是一个外部ComponentDefinition。

//当查看某个特定的ComponentDefinition时,认为bean非常重要,

//以便在查看应用程序的整体配置时能够意识到这一点

int ROLE_SUPPORT = 1;

//角色提示表明一个BeanDefinition是提供一个完全背景的角色,并且与最终用户没有关系。

//这个提示用于注册完全是ComponentDefinition内部工作的一部分的bean

int ROLE_INFRASTRUCTURE = 2;

//1、当前Bean父类名称

//如果父类存在,设置这个bean定义的父定义的名称

void setParentName(@Nullable String parentName);

//如果父类存在,则返回当前Bean的父类的名称

@Nullable

String getParentName();

//2、当前Bean的className

//指定此bean定义的bean类名称。

//类名称可以在bean factory后期处理中修改,通常用它的解析变体替换原来的类名称

void setBeanClassName(@Nullable String beanClassName);

//返回此bean定义的当前bean类名称

//需要注意的是,这不一定是在运行时使用的实际类名,以防子类定义覆盖/继承其父类的类名

//此外,这可能只是调用工厂方法的类,或者它 在调用方法的工厂bean引用的情况下甚至可能是空的

//因此,不要认为这是在运行时定义的bean类型,而只是将其用于在单独的bean定义级别进行解析

@Nullable

String getBeanClassName();

//3、bean作用域

//覆盖此bean的目标范围,指定一个新的范围名称

void setScope(@Nullable String scope);

//返回此bean的当前目标作用域的名称,如果没有确定,返回null

@Nullable

String getScope();

//懒加载

//设置这个bean是否应该被延迟初始化。如果{false},那么这个bean将在启动时由bean工厂实例化,

//这些工厂执行单例的立即初始化。

//懒加载

void setLazyInit(boolean lazyInit);

//返回这个bean是否应该被延迟初始化,即不是在启动时立即实例化。只适用于单例bean。

boolean isLazyInit();

//5.依赖关系设置

//设置这个bean依赖被初始化的bean的名字。 bean工厂将保证这些bean首先被初始化。

//

void setDependsOn(@Nullable String… dependsOn);

//返回这个bean依赖的bean名称

@Nullable

String[] getDependsOn();

//6.是否是自动转配设置

//设置这个bean是否是获得自动装配到其他bean的候选人。

//需要注意是,此标志旨在仅影响基于类型的自动装配。

//它不会影响按名称的显式引用,即使指定的bean没有标记为autowire候选,也可以解决这个问题。

//因此,如果名称匹配,通过名称的自动装配将注入一个bean。

void setAutowireCandidate(boolean autowireCandidate);

//返回这个bean是否是自动装配到其他bean的候选者。就是是否在其他类中使用autowired来注入当前Bean的

//是否为被自动装配

boolean isAutowireCandidate();

//7.主候选Bean

//是否为主候选bean 使用注解:@Primary

void setPrimary(boolean primary);

//返回这个bean是否是主要的autowire候选者

boolean isPrimary();

//8.定义创建该Bean对象的工厂类

//指定要使用的工厂bean(如果有的话), 这是调用指定的工厂方法的bean的名称

void setFactoryBeanName(@Nullable String factoryBeanName);

//如果有返回工厂bean的名字

@Nullable

String getFactoryBeanName();

//9.创建该Bean对象的工厂方法

//如果有,指定工厂方法。这个方法先将通过构造函数参数被调用,或者如果参数,将调用该方法的无参数构造

void setFactoryMethodName(@Nullable String factoryMethodName);

//如果存在,返回工厂方法名

@Nullable

String getFactoryMethodName();

//10.返回此bean的构造函数参数值

//返回此bean的构造函数参数值

ConstructorArgumentValues getConstructorArgumentValues();

default boolean hasConstructorArgumentValues() {

return !getConstructorArgumentValues().isEmpty();

}

//11.获取属性

MutablePropertyValues getPropertyValues();

default boolean hasPropertyValues() {

return !getPropertyValues().isEmpty();

}

//12.设置初始方法

void setInitMethodName(@Nullable String initMethodName);

@Nullable

String getInitMethodName();

void setDestroyMethodName(@Nullable String destroyMethodName);

@Nullable

String getDestroyMethodName();

void setRole(int role);

//13.当前Bean的角色

//获取这个bean的角色

int getRole();

void setDescription(@Nullable String description);

//14.可读描述

//返回对bean定义的可读描述

@Nullable

String getDescription();

//返回该bean定义来自的资源的描述

@Nullable

String getResourceDescription();

//返回原始的BeanDefinition;如果没有,则返回null。允许检索装饰的bean定义

@Nullable

BeanDefinition getOriginatingBeanDefinition();

//15.当前Bean的基本特性

//是否是单例的

boolean isSingleton();

//是否是多例的

boolean isPrototype();

//是否是抽象类

boolean isAbstract();

}

从上面的属性和方法分析可以看出,BeanDefinition对于一个Bean的描述做了比较完整的一套约束。这为后续的实现类提供了最基本的职责和属性。BeanDefinition只是一个接口,它的具体实现如下所示:

在这里插入图片描述

二、BeanDefinitionRegistry


BeanDefinitionRegistry 继承了 AliasRegistry 接口,其核心子类有三个:SimpleBeanDefinitionRegistryDefaultListableBeanFactory以及GenericApplicationContext,类机构图如下所示:

在这里插入图片描述

AliasRegistry 作为 BeanDefinitionRegistry 的顶层接口,它的作用主要为别名管理的通用型接口, AliasRegistry 定义了一些别名管理的方法。

public interface AliasRegistry {

void registerAlias(String name, String alias);

void removeAlias(String alias);

boolean isAlias(String name);

String[] getAliases(String name);

}

BeanDefinitionRegistry 接口在实现AliasRegistry之外还定义了关于 BeanDefinition 注册、注销、查询等一系列的操作。

public interface BeanDefinitionRegistry extends AliasRegistry {

// 向注册表中注册一个新的 BeanDefinition 实例

void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

throws BeanDefinitionStoreException;

// 移除注册表中已注册的 BeanDefinition 实例

void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

// 从注册中取得指定的 BeanDefinition 实例

BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

// 判断 BeanDefinition 实例是否在注册表中(是否注册)

boolean containsBeanDefinition(String beanName);

// 取得注册表中所有 BeanDefinition 实例的 beanName(标识)

String[] getBeanDefinitionNames();

// 返回注册表中 BeanDefinition 实例的数量

int getBeanDefinitionCount();

// beanName(标识)是否被占用

boolean isBeanNameInUse(String beanName);

}

我们可以看下BeanDefinitionRegistry的类实现结构如下所示:

在这里插入图片描述

这里关注下实现类GenericApplicationContext,其中比较重要的方法为registerBeanDefinition,它完成了BeanDefinition的注册 :

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后,附一张自己面试前准备的脑图:

image

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

image

  • Spring全家桶(实战系列)

image.png

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

image

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
ZF8P-1713335011166)]

  • Spring全家桶(实战系列)

[外链图片转存中…(img-tvEFpU61-1713335011166)]

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-17wUIWur-1713335011167)]

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值