Spring 源码学习 09:refresh 大概流程

简介: 前面的准备工作结束之后,就是进入核心代码 refresh。

网络异常,图片无法展示
|


前言


前面的准备工作结束之后,就是进入核心代码 refresh。


源码


public void refresh() throws BeansException, IllegalStateException {
    // 加锁
    synchronized (this.startupShutdownMonitor) {
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
        // 准备一些上下文
        prepareRefresh();
        // 获取准备后的 beanFactory  DefaultListableBeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 准备 BeanFactory
        prepareBeanFactory(beanFactory);
        try {
            // 允许在上下文子类中对bean工厂进行后处理。
            postProcessBeanFactory(beanFactory);
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // 在上下文中调用注册为 beanFactory 后置处理器
            // 就是实现了 BeanFactoryPostProcessor 的 bean
            invokeBeanFactoryPostProcessors(beanFactory);
            // 注册后置处理的Bean到容器当中
            // 就是扩展了 BeanPostProcessor 的 Bean
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();
            // 为此上下文初始化消息源。
            // 初始化国际化工具 MessageSource
            initMessageSource();
            // 为此上下文初始化事件广播器。
            initApplicationEventMulticaster();
            // 在特定上下文子类中初始化其他特殊bean。子类可以自己实现
            onRefresh();
            // 检查并注册监听器。
            registerListeners();
            // 实例化所有剩余的(非延迟初始化)单例。
            finishBeanFactoryInitialization(beanFactory);
            // 最后一步: 完成此上下文的刷新,调用 LifecycleProcessor 的 onRefresh()方法并发布
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }
            // 销毁已创建的单例以避免资源悬挂。
            destroyBeans();
            // 重置活动状态
            cancelRefresh(ex);
            // Propagate exception to caller.
            throw ex;
        }
        finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
            contextRefresh.end();
        }
    }
}

源码就是密密麻麻的一大堆,源码上有相应的注释。

网络异常,图片无法展示
|

下面就根据流程,一步一步的深入源码,了解到每一步都是做什么了。


容器刷新准备

prepareRefresh 这一步主要是准备一些上下文信息。就不过多介绍了。


obtainFreshBeanFactory

网络异常,图片无法展示
|

下面关注初始化 BeanFactory 这一步:

进入源码:

网络异常,图片无法展示
|


通过 Debug 可以看出 refreshBeanFactory() 这一步调用的是 org.springframework.context.support.GenericApplicationContext#refreshBeanFactory 中实现的方法。


继续跟进

网络异常,图片无法展示
|


发现这块判断了一个 refreshed 刷新状态。

refreshBeanFactory 方法也有另一个实现是在 AbstractRefreshableApplicationContext 中, 只不过我的断点没有断进去,这块也一起看下。

protected final void refreshBeanFactory() throws BeansException {
    // 如果存在 BeanFactory 则销毁 Bean 并关闭 BeanFactory
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建一个默认的 BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        // 设置属性
        customizeBeanFactory(beanFactory);
        // 加载 Bean 信息
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

其中会创建 BeanFactory 并加载 BeanDefinition。只不过我暂时没有断到,所以等后面遇到之后再详细介绍。


总结


网络异常,图片无法展示
|

本文简单介绍了 refresh 的流程,并介绍了前两个部分:

  1. prepareRefresh 准备上下文信息
  2. obtainFreshBeanFactory 初始化 BeanFactory
目录
相关文章
|
11天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
1天前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
20 9
|
21天前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
33 9
|
22天前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
19 1
|
27天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
27天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
26天前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
51 2
|
26天前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
47 1
|
26天前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
19 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
26天前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
21 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现