Spring refresh()源码解析

yizhihongxing

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 在此时尚未可用。

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

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

相关文章

  • PHP中Trait及其应用详解

    PHP中Trait及其应用详解 什么是Trait Trait 是 PHP 5.4.0 开始新增的功能之一,可以更加灵活的组合类的代码,实现代码复用和避免多重继承的问题。 简单说,Trait 是一种类似于类的机制,但不能直接实例化的“代码块”,可以在类中使用,甚至可以在多个类中共享使用。 Trait 本身没有实现机制,只是用于分发代码功能,可以视为是(预定义的…

    other 2023年6月27日
    00
  • Python作用域用法实例详解

    Python作用域用法实例详解 Python中的作用域(Scope)指的是变量的可访问范围。了解作用域的概念对于编写可维护和可扩展的代码非常重要。本攻略将详细讲解Python中的作用域用法,并提供两个示例说明。 全局作用域(Global Scope) 全局作用域是指在整个程序中都可以访问的变量。在函数外部定义的变量属于全局作用域。下面是一个示例: x = 1…

    other 2023年8月19日
    00
  • docker容器服务重启

    Docker容器服务重启 在运行Docker容器时,可能会遇到某些容器无法访问、出现错误或停止响应等问题。解决这些问题的一种方法是重启服务,重新启动所有相关的容器。本文将介绍如何使用Docker命令和Docker Compose来重启Docker容器服务。 使用Docker命令重启单个容器 如果你只需要重启单个容器,而不是整个服务,可以使用Docker命令来…

    其他 2023年3月29日
    00
  • 详解Linux系统中设置SFTP服务用户目录权限的方法

    下面是详解“详解Linux系统中设置SFTP服务用户目录权限的方法”的完整攻略: 安装SFTP服务器软件 在Linux系统中,使用SFTP服务需要先安装SFTP服务器软件。目前,主流的SFTP服务器软件有OpenSSH和vsftp。其中,OpenSSH是Linux内置的SFTP服务器软件,可以通过以下命令来安装: sudo apt-get update su…

    other 2023年6月27日
    00
  • docker mysql启动时执行初始化sql

    想要在docker中启动MySQL时自动执行初始化sql文件,可以通过以下步骤来实现: 1. 创建一个目录用于存放初始化文件 我们首先需要创建一个目录,用于存放我们的初始化sql脚本文件。 $ mkdir db_init_sql 2. 编写初始化sql脚本文件 在创建的目录下,我们需要创建一个或多个初始化sql脚本文件。这些sql文件包含了我们要在MySQL…

    other 2023年6月20日
    00
  • tplink管理员初始密码是多少 TPLINK路由器重置密码教程

    TPLINK管理员初始密码是多少? 对于大部分的TPLINK路由器来说,管理员的初始密码是“admin”。但是有些型号的TPLINK路由器可能会使用其他的默认密码,建议在使用路由器前通过产品说明书或者官网获取对应型号的初始管理员密码。如果用户在使用路由器前对管理员密码进行了更改,但又忘记了密码,可以通过重置路由器来恢复管理员权限。 TPLINK路由器重置密码…

    other 2023年6月27日
    00
  • spring中AOP 注解开发示例详解

    针对“spring中AOP 注解开发示例详解”的完整攻略,我将分为以下几个部分进行讲解: 1. AOP 概述 AOP,即 Aspect Oriented Programming,面向切面编程,是一种程序设计的思想,可以让程序逻辑分散到各个部分,从而增加代码的可维护性和辅助性。Spring框架提供了完善的AOP实现,可以通过纯Java编写切面代码,实现统一的业…

    other 2023年6月27日
    00
  • cartographer分析

    Cartographer分析的完整攻略 Cartographer是一种常用的SLAM(Simultaneous Localization and Mapping)算法,它可以通过激光雷达等传感器数据,实现机器人的自主定位和地构建。本文将提供一份关于Cartographer分析的完整攻略,包括定义、用法、示例说明以注意事项。 定义 Cartographer是一…

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