共计 1993 个字符,预计需要花费 5 分钟才能阅读完成。
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, 并触发非懒加载成品的创建.
欢迎大家关注我的公众号【源码行动】,最新个人理解及时奉送。