Spring精讲:什么是BeanFactory?

Spring精讲:什么是BeanFactory?(附源码)

我们可以看到DefaultListableBeanFactory实现的接口有:

  • SingletonBeanRegistry: 定义了对单例缓存池相关的操作,如将bean注册到单例缓存池中

  • ConfigurableBeanFactory: 可配置的BeanFactory,定义了各种各样的配置能力,如bean的作用域,bean的classLoader,添加bean的后置处理器,设置bean的创建状态,销毁bean等等

  • AutowireCapableBeanFactory: 能进行自动装配的BeanFactory,这可能是我们最为熟悉的BeanFactory,定义了自动装配的类型(byName/byType),createBean, autowireBean, 自动装配属性, populateBean, initializeBean, 对于与bean生命周期相关的方法都将在这里体现

  • ListableBeanFactory: 对BeanFactory的增强,定义了一系列根据beanType获取bean或者beanName的方法

  • ConfigurableListableBeanFactory: 对ConfigurableBeanFactory的增强,定义了忽略bean的类型、缓存bean定义、预实例化单例bean等方法

  • BeanDefinitionRegistry: bean定义注册器,定义了与bean定义相关的方法

如果说以上的接口体现了DefaultListableBeanFactory具备的功能,那么它所继承的一系列类就是这些功能的实现:

  • DefaultSingletonBeanRegistry: 单例bean注册器,定义了三级缓存,其实就是三个Map属性

  • FactoryBeanRegistrySupport: 提供对FactoryBean的支持

  • AbstractBeanFactory: 实现了一系列操作IOC容器的功能,但最终的createBean依旧交由子类AbstractAutowireCapableBeanFactory完成

  • AbstractAutowireCapableBeanFactory: 实现了创建bean的功能,所有与创建bean的相关的功能都在这里

  • DefaultListableBeanFactory: 在以上父类的功能基础上实现了ConfigurableBeanFactory和BeanDefinitionRegistry接口,定义了一些存放Bean定义相关信息的Map

> 看到这里,想必对DefaultListableBeanFactory已经有一个大致的了解了,那么问题来啦,我们应该怎么从容器中获取一个bean呢?是不是只要通过BeanDefinitionRegistry注册一个bean定义,再通过AutowireCapableBeanFactory去createBean就完成了呢?就像下面这样:

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class);

beanFactory.registerBeanDefinition(“wheel”,beanDefinition);

beanFactory.getBean(“wheel”, Wheel.class);

Bean的元信息从何而来?

=============

我们现在已经知道DefaultListableBeanFactory的大致功能了,我们发现当我们想要创建一个Bean的时候,总是离不开一个名词:Bean定义,那么这个Bean定义究竟是什么呢?

BeanDefinition其实是一个接口,并不是一个具体的类,我们也可以看一下它的UML图:

Spring精讲:什么是BeanFactory?(附源码)

可以发现这里使用了模板方法的设计模式扩展了许多的子类,其中我们最常用的为RootBeanDefinition,它主要包含的属性如下:

Spring精讲:什么是BeanFactory?(附源码)

我们向容器中注册的Bean定义的信息大概就是如此,当BeanFactory生产Bean时,便可以通过beanClass清楚的知道Bean的类是什么,作用域是怎样,是否懒加载,init方法是什么等等等等

> 咦,如果一个最简单的bean,好像可以直接通过反射就搞定了耶~

具体结构已经清楚了,那我们来看一下注册过程吧

先从Demo看起

========

public static void main(String[] args) {

//创建一个DefaultListableBeanFactory实例

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

//创建一个BeanDefinition

RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class);

//将BeanDefinition注册到容器中

beanFactory.registerBeanDefinition(“wheel”,beanDefinition);

}

public static class Wheel {

}

创建BeanDefinition

================

public RootBeanDefinition(@Nullable Class beanClass) {

//初始化父类

super();

//将beanClass赋值给this.BeanClass

setBeanClass(beanClass);

}

初始化父类

//将其中一部分属性赋予默认值

autowireCandidate = true;

primary = false;

protected AbstractBeanDefinition() { this(null, null);

}protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) { this.co 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 nstructorArgumentValues = cargs;

this.propertyValues = pvs;

}

将BeanDefinition注册到容器中

=====================

//除去校验逻辑,注册时只做了这两步操作

this.beanDefinitionMap.put(beanName, beanDefinition);

this.beanDefinitionNames.add(beanName);

看到这里,大家伙可能会充满疑问?what? 就这样?没有填充属性的步骤吗?嘿嘿,BeanFactory是一个纯粹的工厂,只负责生产Bean,是没有装配(设计)BeanDefinition的功能的,专业的事还是交给专业的人做,设计的事情还是交由ApplicationContext完成的。

那在ApplicationContext中是怎么完成一个BeanDefinition的呢?还记得预启动将配置类注册到容器中时有这样一段代码吗?以下代码为AnnotatedBeanDefinitionReader#doRegisterBean中的摘要部分:

void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,

@Nullable Class [] qualifiers, BeanDefinitionCustomizer… definitionCustomizers) {

//…代码 //处理普通的bean定义注解,@Lazy @Primary @DependsOn @Role @Description AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //…代码 }

而非配置的Bean是通过在预启动时注册的配置类后置处理器ConfigurationClassPostProcessor#processConfigBeanDefinitions中完成的,以下代码为ClassPathBeanDefinitionScanner#doScan中的摘要部分,详细调用链将在后面的文章进行说明

//传入我们配置类的包路径

protected Set doScan(String… basePackages) { Set beanDefinitions = new LinkedHashSet<>();

for (String basePackage : basePackages) {

//寻找到所有标识了@Component注解的BeanDefinition

Set candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) {

//…省略代码

if (candidate instanceof AbstractBeanDefinition) {

//处理BeanDefinition

postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) {

//处理普通的bean定义注解,@Lazy @Primary @DependsOn @Role @Description

AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //…省略代码

//将BeanDefinition注册到容器中

registerBeanDefinition(definitionHolder, this.registry);

} }

处理BeanDefinition

protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {

//设置默认值

beanDefinition.applyDefaults(this.beanDefinitionDefaults);

//这里默认为空

if (this.autowireCandidatePatterns != null) {

beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));

}}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值