spring源码分析系列3BeanFactory核心容器的研究

3次阅读

共计 3814 个字符,预计需要花费 10 分钟才能阅读完成。

在讲容器之前,再明确一下知识点。

  • BeanDefinition 是 Bean 在容器的描述。BeanDefinition 与 Bean 不是一个东西。
  • Bean 是根据 BeanDefinition 创建出来的。也即是我们所说的对象。

BeanDefinition 物料需要有地方存储,Bean 成品需要有地方存。今天我们讲讲仓库。

BeanFactory 家族


此图是默认容器 DefaultListableBeanFactory 的继承, 实现关系图. 我们从右向左来分析下.

  1. BeanFactory 接口:容器顶级接口,提供了容器最基本的能力,包括获取 bean, 是否包含 bean, 是否单例,获取 bean 类型,Bean 的别名等方法。
  2. ListableBeanFactory 接口:BeanFactory 的子接口;具有批量获取 Bean 的能力
  3. HierarchicalBeanFactory 接口:具有访问父容器的能力。有层次的 BeanFactory。
  4. AutowireCapableBeanFactory 接口:继承 BeanFactory,扩展了自动装配能力。这个接口更多的作用是用于于与其他框架集成,把不在 spring 容器中的 Bean 加入到 Spring 容器生命周期管理中来。此接口很少用
  5. ConfigurableBeanFactory:定义了 BeanFactory 的配置。继承 HierarchicalBeanFactory 和 SingletonBeanRegistry 接口。实现了此接口的容器,具有层次,单例 BeanDefinition 注册功能。
  6. ConfigurableListableBeanFactory:大融合接口,除了具有上述接口的能外,还具有: 类加载器, 类型转化, 属性编辑器,BeanPostProcessor, 作用域,bean 定义, 处理 bean 依赖关系, bean 销毁等功能。
  7. SingletonBeanRegistry 接口: 具有 Bean 的操作能力. 注册, 查询, 获取 Bean 数量等能力. 注意此处的 Bean 是实例. 区别于 BeanDefinition.
  8. SimpleAliasRegistry:Bean 的别名操作类, 实现了 AliasRegistry. 具有存储 Bean 别名, 注册 Bean 别名, 获取 Bean 别名的功能.aliasMap 属性存储 Bean 别名
  9. DefaultSingletonBeanRegistry: 除了继承了 SimpleAliasRegistry 的功能外. 最重要的是实现了 SingletonBeanRegistry 接口. 具有存储 Bean 实例, 注册 Bean, 获取 Bean 的能力. 我们定义的被 Spring 管理的 Class 类的实例对象, 以及实例的之间的相互依赖关系都是存储在此类中. 默认常用的容器 DefaultListableBeanFactory 的 Bean 的相关能力. 就是通过间接继承此类来实现的.
    /** Disposable bean instances: bean name --> disposable instance */
    private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();

    /** Map between containing bean names: bean name --> Set of bean names that the bean contains */
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);

    /** Map between dependent bean names: bean name --> Set of dependent bean names */
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

    /** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64)
  1. FactoryBeanRegistrySupport: 提供多工厂 Bean 的支持.FactoryBean 通过其名字我也可以看出是生产 Bean 的 Bean.
  2. AbstractBeanFactory 抽象类: 承上启下 . 从图中我们看出. AbstractBeanFactory. 通过继承关系, 继承 FactoryBeanRegistrySupport 各种能力. 而且实现了右边部分接口. 已然是比较完备的 Bean 容器了.AbstractBeanFactory 还通过模板模式定义了获取 Bean 的算法骨架,
  3. AbstractAutowireCapableBeanFactory: . 具有大部分的能力. 实现了 AbstractBeanFactory 定义的模板方法. 其中 doCreateBean 方法逻辑是把一个 BeanDefinition 变成 Bean 的过程. 这个方法非常重要 . 通常我们使用类创建对象. 直接 new 出来. spring 把 BeanDefinition 到 Bean 的过程模板化, 留下了很多扩展点. 留给使用者可以在不同的时刻自定义 BeanDefition 创建 Bean 的过程.
  4. DefaultListableBeanFactory 常用的默认容器实现, 也是 spring 最常使用的容器类. 看左边 DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口. 这说明什么? 说明 DefaultListableBeanFactory 具有存储 BeanDefinition, 操作 BeanDefinition 的能力.DefaultListableBeanFactory 通过继承关系也具有了 Bean 的存储操作功能.

小结 :

  1. BeanFactory 体系,接口分明,完美的体现了接口分离原则。
  2. BeanFactory 体系中有两种存储, 一种是 BeanDefinition 的存储, 另一个是 Bean 的存储.
  3. DefaultListableBeanFactory 作为最常用的容器类. 不但具有 BeanDefinition 的存储操作功能, 而且通过继承具有 Bean 的存储操作功能.DefaultListableBeanFactory 把存储的 BeanDefinition 通过一定算法创建 Bean 并存储起来 .

BeanDefinition,BeanFactory,Bean 三者关系

通过上面的对各个接口, 类的认识. 我们再来看看三者的关系.

我们向 BeanFactory 容器中注入一个 BeanDefinition。BeanFactory 帮我们存储起来. 当我们想要得到一个 Bean 时.BeanFactory 帮我们把 BeanDefinition 创建 Bean. 并缓存起来. 这个创建过程是可参与的 .

  • BeanFactory 保存了 BeanDefiniton 与 Bean.
  • BeanFactory 具有使用 BeanDefinition 创建 Bean 的功能
  • BeanFactory 允许使用者可以干预 BeanDefinition 生成 Bean 的功能.

BeanFactory 中的扩展点

设计原则之开闭原则说的特别好:说一个软件实体应该通过扩展来实现变化.
很多优秀的框架都有类似的扩展点设计, 列如:

  • Tomcat 中的 Filter
  • Tomcat 中的 pipline-valve
  • springmvc 中的 Interceptor

BeanFactory 中从 BeanDefinition 到 Bean 并不是一下子就完成的. 这有一个过程.spring 正是在这个过程中留下扩展点. 来实现 BeanDefinition 到 Bean 的过程中的各种自定义变化.

从上面我们得知:AbstractAutowireCapableBeanFactory 中有个 doCreateBean() 正是 BeanDefinition 到 Bean 的创建方法. 接下来我们看看这个方法. 有哪些扩展点:

  1. xxxAware 接口: 使 Bean 可以获得 xxx. 列如实现了 BeanFactoryAware 接口的类,可以在该 Bean 被加载的过程中获取加载该 Bean 的 BeanFactory
  2. BeanPostProcessor:BeanPostProcessor 接口定义的两个方法,分别在 bean 的初始化方法(InitializingBean 接口,或者 init-method 定义)执行的前后执行
  3. InitializingBean 接口: 实现了 InitializingBean 接口的类, 执行 afterPropertiesSet
  4. 自定义的 init-method 方法:

总结:

BeanFactory 是物料与成品仓库,并配生产线,把 BeanDefinition 生产成 Bean。BeanFactory 留下很多扩展点, 方便开发人员可以参与 BeanDefinition 到 Bean 的创建过程.

欢迎大家关注我的公众号【源码行动】,最新个人理解及时奉送。

正文完
 0