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技术站