Spring 容器启动时所执行的各项操作

Spring 容器启动时所执行的各项操作

Spring 中的 AbstractApplicationContext 是 ApplicationContext 的抽象实现类,该实现类的 refresh() 方法定义了 Spring 容器在加载配置文件后的各项处理过程,这些处理过程氢气的刻画了 Spring 容器启动时所执行的各项操作。下面来看下 refresh() 内部定义了哪些执行逻辑。

                // 1.初始化 BeanFactory
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

                // 交给子类处理 BeanFactory
                postProcessBeanFactory(beanFactory);
                // 2.调用工厂后处理器
                invokeBeanFactoryPostProcessors(beanFactory);
                // 3.注册 Bean 后处理器  
                registerBeanPostProcessors(beanFactory);
                // 4. 初始化消息源
                initMessageSource();
                // 5.初始化应用上下文事件广播器
                initApplicationEventMulticaster();
                // 6. 初始化其他特殊的Bean , 由具体子类实现
                onRefresh();
                // 7. 注册事件监听器
                registerListeners();
                // 8. 初始化所有单实例的 Bean ,使用 懒加载模式的 Bean 除外
                finishBeanFactoryInitialization(beanFactory);
                // 9.完成刷新并发布容器刷新事件
                finishRefresh();

  1. 初始化 BeanFactory : 根据配置文件初始化 BeanFactory ,在 obtainFreshBeanFactory() 方法中,首先调用 refreshBeanFactory() 方法刷新 BeanFactory , 然后调用 getBeanFactory() 方法获取 BeanFactory ,这两个方法具体都是由子类实现。这一步里, Spring 将配置文件的信息装入 Bean 定义注册表中 BeanDefintionRegistry 中,但此时 Bean 还未初始化。

  2. 调用工厂后处理器: 根据反射机制从 BeanDefintionRegistry 中找出所有实现了 BeanFactoryPostProcessor 接口的 Bean ,并调用其

postProcessBeanFactory() 方法。

  1. 注册 Bean 后处理器 : 根据反射机制从 BeanDefintionRegistry 中找出所有实现了 BeanPostProcessor 接口的 Bean ,并将它们注册到容器 Bean 后处理器的注册表中。

  2. 初始化消息源 :初始化容器的国际化消息源。

  3. 初始化应用上下文事件广播器。

  4. 初始化其他特殊的 Bean :这个一个钩子方法,子类可以借助这个方法执行一些特殊的操作,如 AbstractRefreshableApplicationContext 使用该方法执行初始化 ThemeSource 的操作。

  5. 注册事件监听器。

  6. 初始化所有单例的 Bean,使用懒加载的 Bean 除外,初始化 Bean 后,将其放入 Spring 容器的缓存池中。

  7. 发布上下文刷新事件:创建上下文刷新事件,事件广播器负责将这些事件广播到每个注册的事件监听器中。

在文章的上一步部分,我们看到了 Bean 从创建到销毁的生命历程,这些过程都可以从上面的流程中找到对应的步骤。Spring 协调多个组件共同完成这个复杂的作业流程。如下图描述了 Spring 容器从加载配置文件到创建处一个完整的 Bean 的作业流程及参与的角色 。

  1. ResourceLoader 从存储介质中加载 Spring 配置信息 , 并使用 Resource 表示这个配置文件资源 。

  2. BeanDefinitionReader 读取 Resource 所指向的配置资源,然后解析配置文件。配置文件中的每个 <bean> 解析成一个 BeanDefinition 对象,并保存到 BeanDefinitionRegistry 中。

  3. 容器扫描 BeanDefinitionRegistry 中的 BeanDefinition ,使用 Java 反射机制自动识别出 Bean 工厂后处理器 (实现 BeanFactoryPostProcessor 接口的 Bean),然后调用这些 Bean 工厂后处理器对 BeanDefinitionRegistry 中的 BeanDefinition 进行加工处理。主要完成以下两项工作 :
    (1).对使用占位符的 <bean> 元素标签进行解析,得到最终的配置值。这意味着对一些半成品式的 BeanDefinition 对象进行加工处理并得到成品的 BeanDefinition 对象。
    (2).对 BeanDefinitionRegistry 中的 BeanDefinition 进行扫描,通过 Java 反射机制找出所有属性编辑器的 Bean (实现 Java.beans.PropertyEditor 接口的 Bean),并自动将它们注册到 Spring 容器的属性编辑器注册表中(PropertyEditorRegistry)。

  4. Spring 容器从 BeanDefinitionRegistry 中取出加工后的 BeanDefinition ,并调用 InstantiationStrategy 进行 Bean 实例化工作。

  5. 在实例化 Bean 时,Spring 容器将使用 BeanWrapper 对 Bean 进行封装。 BeanWrapper 提供了很多以 Java 反射机制操作 Bean 的方法,它将结合该 Bean 的 BeanDefinition 及容器中的属性编辑器,完成 Bean 属性注入工作。

  6. 利用容器中注册的 Bean 后处理器(实现 BeanPostProcessor 接口的 Bean)对已完成属性设置工作的 Bean 进行后续加工,直接装配出一个准备就绪的 Bean 。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值