乐趣区

spring源码分析系列4ApplicationContext研究

ApplicationContext 接口

首先看一下一个最基本的上下文应该是什么样子

ApplicationContext 接口的注释里写的很清楚:
一个基本 applicationContext 应该提供:

  • 访问 Bean 的能力
  • 提供加载资源的能力
  • 发布事件的能力
  • 解析消息、支持国际化的能力

AbstractApplicationContext 承上启下

ConfigurableApplicationContext 接口:

大部分上下文都实现了此接口. 此接口除了继承了 ApplicaitnContext 接口的能力外. 还具有可配置上下文与生命周期管理功能.
其中最重要的是定义了 refresh()方法. refresh()功能是加载配置.

AbstractApplicationContext 抽象类:

大部分上下文都继承了此类.AbstractApplicationContext 可以说启到承上启下的作用.

从继承图我们看, AbstractApplicationContext 实现了大部分的接口方法.
其中 refresh()方法的实现. 为 ApplicationContext 提供了加载配置的能力.

加载的什么配置呢?
其实: 所谓加载的配置大部分都是加载 Bean

ApplicationContext 与 BeanFactory 关系

上节分析了 BeanFactory 存储 BeanDefinition 与 Bean. 并且 BeanFactory 的 createBean()方法可以将 BeanDefinition 创建成 Bean.

要想从 BeanFactory 中获取 Bean, 就得先有 BeanDefinition. 有了 BeanDefinition, 还要触发 BeanDefinition 到 Bean 的创建.

这里就产生了两个问题:

  • BeanDefinition 从哪里来?
  • 创建过程在哪里触发的?

ApplicationContext 扮演的角色也就显而易见了.

ApplicationContext 初始化的核心工作是将散落在各个目录下的各种配置形式的 Bean 定义, 搜集起来解析成 BeanDefinition 并入库到 BeanFactory. 然后触发 BeanDefinition 创建成 Bean, 存到 BeanFactory 中

至此: 整个 spring 启动的脉络就也清晰了. 两大块:Bean 定义的搜集 +Bean 的创建.

`
[开发人员]– 标注 –>[Bean 定义] – 搜集 –> [BeanDefinition] – 创建 –>[Bean]
`

ApplicationContext 重要工作

开发人员常用的标注 Bean 定义的方式有.

  • xml 文件标注 Bean 定义
  • 注解标注 Bean 定义

ApplicationContext 将这些 Bean 定义转为 BeanDefinition 并不是那么容易.

第一步 搜集: 需要把散落的 Bean 定义的载体找到. 搜集起来.(注意,ApplicationContext 搜集 Bean 定义的过程其实也是通过调用工具来执行的)

  • XML 对应的有 XmlBeanDefinitionReader 搜集器
  • 注解 JavaConfig 对应的有 ClassPathBeanDefinitionScanner 收集器

第二步 解析. 将 XML 或者 JavaConfig 中的标注了 Bean 定义的转为 BeanDefinition

第三步:扩展点.BeanFactoryPostProcessor. 实现了此接口的类可以在 BeanDefinition 入库到 BeanFactory 的这个阶段中, 修改 BeanDefinition 信息. 这也是 spring 留下的扩展点。

BeanDefinitionRegistryPostProcessor 与 BeanFactoryPostProcessor 与 BeanPostProcessor 区别:

  • BeanFactoryPostProcessor:可以修改 BeanDefinition。发生在 BeanDefinition 入库到 BeanFactory 阶段.
  • BeanDefinitionRegistryPostProcessor 继承与 BeanFactoryPostProcessor:单从名字上看,我们可以看出,这个 PostProcessor 跟 BeanDefinition 注册有关。他发生的阶段比 BeanFactoryPostProcessor 更早,他用来注册 BeanDefinition 用。实现了此接口的可以看作一个 BeanDefinition 扫描注册器。
  • BeanPostProcessor:发生在 BeanDefinition 创建 Bean 阶段。

总结:

BeanDefinition 是物料
Bean 是成品
BeanFactory 存储物料, 存储成品.
ApplicationContext 初始化: 搜集物料, 入库到 BeanFactory, 并触发非懒加载成品的创建.
欢迎大家关注我的公众号【源码行动】,最新个人理解及时奉送。

退出移动版