什么是BeanFactory?
提到Spring,总是让人第一时间想起IOC容器,而IOC容器的顶层核心接口就是我们的BeanFactory,如果能够理解BeanFactory的体系结构想必能让我们对Spring整体脉络有更加清晰的认知,所以,本文的探究方向主要为以下几点:
BeanFactory的体系结构是怎样的?
Bean的元信息从何而来?
BeanFactory生产Bean的过程是怎样的?
BeanFactory的体系结构我们先来看看有哪些子类实现了它吧
其中ApplicationContext这一块已在上篇文章有详细说明,而DefaultListableBeanFactory这个底层实现类便理所当然的成为了我们此次探究的出发点,为了让我们有个更好的观感,以下是纯粹的BeanFactoryUML图:
我们可以看到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图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
可以发现这里使用了模板方法的设计模式扩展了许多的子类,其中我们最常用的为RootBeanDefinition,它主要包含的属性如下:
我们向容器中注册的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); }