Spring refresh()源码解析

Spring refresh()源码解析

什么是Spring refresh()方法?

refresh()是Spring中负责刷新ApplicationContext的方法,它会重新读取配置文件、重新实例化和初始化Bean对象,同时注入新创建的对象。它是在Spring启动时被调用的方法。

refresh()方法的过程是怎样的?

refresh()方法的整个过程大致分为以下几个步骤:

1. prepareRefresh()方法

该方法主要是为了準备 ApplicationContext 的信息,包括:
* 关闭 ApplicationContext 的状态设置为 False
* 初始化资源加载器
* 记录 ApplicationContext 的启动时间

2. obtainFreshBeanFactory()方法

该方法会刷新 BeanFactory,形成应用中定义的所有 bean 的定义和关系列表,包括:
* 使用 AbstractRefreshableApplicationContext 的 refreshBeanFactory() 方法加载 BeanFactory
* 使用 ConfigurableBeanFactory 的 setSerializationId() 方法设置序列化 ID
* 注册环境相关的 BeanDefinition

3. prepareBeanFactory()方法

该方法主要是为了将 Spring 配置文件中的信息加载到 BeanFactory 中,包括:
* 设置 BeanFactory 的 ClassLoader
* 添加 ApplicationContextAwareProcessor 的 BeanPostProcessor
* 添加 BeanFactoryAwareProcessor 的 BeanPostProcessor
* 添加与“当前环境”相关的 BeanPostProcessor
* 设置忽略的自动装配接口
* 注册默认的 bean
* 注册 BeanFactory 自定义的编辑器
* 注册 Spring 带有的 JAVA API 编辑器
* 设置表达式语言

4. postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法

该方法主要是对 BeanFactory 进行后处理,包括:
* 注册 BeanPostProcessors
* 执行 Scopes 的注册
* 注册 Scope 回调
* 引入相关的依赖注入 BeanPostProcessor
* 初始化 MessageSources 组件

5. invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)方法

该方法主要是执行 BeanFactoryPostProcessor ,包括:
* 按优先级排序执行 BeanDefinitionRegistryPostProcessor
* 按优先级排序执行 BeanFactoryPostProcessor
* 调用 ApplicationListenerDetector

6. registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)方法

该方法主要是为 BeanFactory 注册 BeanPostProcessor,包括:
* 添加了 BeanPostProcessorChecker,确保 BeanPostProcessor 的总数匹配 BeanFactory 中的 Bean 的总数
* 使用 InstantiationAwareBeanPostProcessor 接口处理程序
* 使用 SmartInstantiationAwareBeanPostProcessor 接口处理程序

7. initMessageSource()方法

该方法主要是初始化信息源 MessageSource

8. initApplicationEventMulticaster()方法

该方法主要是初始化 ApplicationEventMulticaster 用来监听 ApplicationContext 发布的事件

9. onRefresh()方法

该方法主要提供子类覆盖,以便在 ApplicationContext 已成功刷新并激活所有 bean 之后执行特定的处理

10. registerListeners()方法

该方法主要是向 ApplicationEventMulticaster 注册特定的监听器

11. finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法

该方法主要是完成 BeanFactory 的初始化,包括:
* 调用所有未调用的 BeanFactoryPostProcessor,执行 AfterInitialization
* 让所有 BeanPostProcessor 检查匹配 Bean 中的 Bean
* 调用 postProcessorsBeforeInitialization() 和 postProcessorsAfterInitialization()
* 调用所有实现了 InitializingBean 的 Bean 的 afterPropertiesSet() 方法
* 调用自定义的 init 方法

12. finishRefresh()方法

该方法主要是为了清除 Spring 的所有剩余缓存

示例说明

示例1

我们现在假设有一个ApplicationContext,它包含了一个foo bean,当执行refresh()方法时,Spring 将刷新所有 bean,并将 foo bean 重新加载到容器中。

ApplicationContext ctx = ... // create ApplicationContext
// 此时foo bean已被加载到ctx中
ctx.getBean("foo");
ctx.refresh();
// 调用refresh()方法之后,foo bean被重新加载到ctx中
ctx.getBean("foo");

示例2

在这个示例中,我们将会在refresh()方法中使用 setServletContext() 方法设置 ServletContext 接口,以便在 ApplicationContext 中进行注册。

ApplicationContext ctx = ... // create ApplicationContext
ServletContext servletContext = ... // create ServletContext
ctx.setServletContext(servletContext);
ctx.refresh();

在这一示例中,如果在refresh()方法之前没有设置 ServletContext 接口,则会出现异常。这是因为某些 bean 是通过 ServletContext 实例进行注入的,而 ServletContext 在此时尚未可用。

阅读剩余 66%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring refresh()源码解析 - Python技术站

(0)
上一篇 2023年6月20日
下一篇 2023年6月20日

相关文章

  • 侠客风云传妹子男主结局是什么 侠客风云传全结局图文介绍

    侠客风云传妹子男主结局攻略 《侠客风云传》是一款受欢迎的角色扮演游戏,玩家在游戏中扮演男主角,与各种妹子展开互动,并最终决定与哪位妹子结局。以下是关于妹子男主结局的详细攻略。 1. 收集好感度 在游戏中,与每个妹子互动可以提高她们对男主角的好感度。好感度是影响结局的重要因素,因此玩家需要与妹子进行对话、完成任务、赠送礼物等方式来提高好感度。每个妹子都有不同的…

    other 2023年7月28日
    00
  • web前端轮询获取数据的定义及优劣

    Web前端轮询获取数据的定义及优劣 Web前端轮询获取数据是一种常见的客户端与服务器通信方式,用于实时获取服务器端的数据。本文将介绍Web前端轮询获取数据的定义优劣,包括轮询的概念、轮询的优劣、轮询的实现方式等。 轮询的概念 轮询是一种客户端与服务器通信方式,客户端定期向服务器发送请求,以获取最新的数据。在Web前端中,轮询通常使用Ajax技术实现,即通过X…

    other 2023年5月9日
    00
  • electron打印

    Electron 打印攻略 Electron 是一个基于 Web 技术的跨平台桌面应用程序开发框架,它可以使用 HTML、CSS 和 JavaScript 构建桌面应用程序。在攻略中,我们将介绍如何在 Electron 应用中实现打印功能,并提供两个示例说明。 打印功能 Electron 提供了一个名为 webContents 的模块,它用于控制应用程序窗口…

    other 2023年5月6日
    00
  • PHP准确取得服务器IP地址的方法

    PHP准确取得服务器IP地址的方法 在PHP中,有几种方法可以准确地获取服务器的IP地址。下面将介绍两种常用的方法。 方法一:使用$_SERVER全局变量 PHP的$_SERVER全局变量包含了与服务器相关的信息,其中包括服务器的IP地址。可以通过访问$_SERVER[‘SERVER_ADDR’]来获取服务器的IP地址。 示例代码: $serverIP = …

    other 2023年7月30日
    00
  • Android开发5:应用程序窗口小部件App Widgets的实现(附demo)

    首先,让我们概括一下“Android开发5:应用程序窗口小部件App Widgets的实现”的实现步骤: 了解App Widget的基本概念和工作原理; 创建App Widget Provider,并在AndroidManifest.xml中声明; 创建App Widget的布局文件; 创建App Widget更新的RemoteViews对象; 更新App …

    other 2023年6月25日
    00
  • css字体样式(Font Style) 属性

    CSS字体样式(Font Style)属性攻略 简介 CSS字体样式(Font Style)属性用于设置文本的字体样式,包括斜体、正常和倾斜。该属性可以应用于任何文本元素。 语法 font-style: normal|italic|oblique; normal:默认值,文本以正常字体样式显示。 italic:文本以斜体字体样式显示。 oblique:文本以…

    other 2023年8月18日
    00
  • mybatis中insert返回值为1,但数据库却没有数据

    MyBatis中insert返回值为1,但数据库却没有数据的解决方法攻略 有时候在使用MyBatis进行数据插入操作时,可能会遇到返回值为1,但实际数据库中却没有插入数据的情况。以下是解决这个问题的完整攻略: 检查数据库连接是否正常:首先,确保数据库连接正常,可以通过连接数据库的其他方式进行验证。 检查数据源配置:确认MyBatis的数据源配置是否正确,包括…

    other 2023年10月18日
    00
  • Python使用Selenium WebDriver的入门介绍及安装教程(最新推荐)

    以下是“Python使用Selenium WebDriver的入门介绍及安装教程(最新推荐)”的完整攻略: 简介 Selenium是一个自动化测试框架,最初是为Web应用程序测试而创建的。 Selenium WebDriver是Selenium的一个分支,它提供了一组API用于自动化操作Web浏览器。 使用Python编写Selenium脚本可以自动完成We…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部