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
目录
相关文章
|
2月前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
9月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
346 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
4月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
8月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
503 70
|
6月前
|
安全 Java 数据库
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
924 2
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
353 2
|
8月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
193 20
|
10月前
|
IDE Java 应用服务中间件
spring boot 启动流程
Spring Boot 启动流程简介: 在使用 Spring Boot 之前,启动 Java Web 应用需要配置 Web 容器(如 Tomcat),并将应用打包放入容器目录。而使用 Spring Boot,只需运行 main() 方法即可启动 Web 应用。Spring Boot 的核心启动方法是 SpringApplication.run(),它负责初始化和启动应用上下文。 主要步骤包括: 1. **应用启动计时**:使用 StopWatch 记录启动时间。 2. **打印 Banner**:显示 Spring Boot 的 LOGO。 3. **创建上下文实例**:通过反射创建
536 5
|
9月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
227 0