上篇讲到 BeanFactory 的初始化过程,Spring 还提供了另外一种拥有更多扩展功能的容器 ApplicationContext。ApplicationContext 比简单 BeanFactory 多出的功能:1、支持不同的信息源。通过继承 MessageSource 接口 2、访问资源。通过继承 ResourceLoader,可以从不同地方得到 Bean 定义资源 3、应用事件。通过继承 ApplicationEventPublisher,引入事件机制,方便管理 Bean 的生命周期。。
我们以 ClassPathXmlApplicationContext 为例分析这类容器的初始化过程。第一步是设置配置文件路径,保存在 configLocations 属性中。重点是后面的 refresh(),其中逻辑清晰地展示了所有的流程:1、准备工作对系统属性和环境属性进行准备和验证 2、初始化 BeanFactory,解析容器中的 bean3、对 BeanFactory 进行各种功能填充 3.1、增加对 SPEl 语言的支持;3.2、增加对属性编辑器的支持,如字符串转 Date;3.3、添加 ApplicationContextAwareProcessor 为了在实现了 EnvironmentAware 等接口的 bean 实例化时取得相应的资源 3.4、设置忽略依赖将 ApplicationContextAwareProcessor 涉及到的 Aware 类在依赖注入的时候忽略 3.5、注册固定依赖为 bean 中 BeanFactory 等属性的注入注册固定的实例 3.6、增加对 AspectJ 的支持(后续会细说)3.7、将相关环境变量及属性以单例模式注册 4、允许子类添加自己的 BeanPostProcessors5、激活 BeanFactoryPostProcessor 在容器所有 bead 实例化前对 bean 配置的元数据进行处理,如 PropertyPlaceholderConfigurer 实现 bean 定义中 ${key} 和配置文件的映射 6、注册 BeanPostProcessor7、初始化消息资源,国际化处理 8、初始化应用事件广播器用于在 context.publishEvent 时根据事件类型遍历对应的监听器 9、允许子类初始化其他的 bean10、查找并注册事件监听器 11、初始化非延迟加载的单例 12、通知生命周期处理器容器启动完毕,发出 ContextRefreshedEvent 事件