Spring 源码解析 | 容器初始化 refresh() 分析

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文主要是讲 Spring 容器的启动过程主要是以题干的方式进行可能不回涉及过多的细节,希望大家阅读本文能对 Spring 容器初始化过程有一个简单的了解。 环境介绍:Spring 5.3.10Jdk 11

创建 Spring 容器


我们创建 Spring 容器可以通过一行代码进行创建


AnnotationConfigApplicationContext applicationContext = 
    new AnnotationConfigApplicationContext(AppConfig.class);


在这个过程中核心就是调用 AnnotationConfigApplicationContext 的构造方法


public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    // 刷新上下文
    refresh();
}


Spring 容器创建过程 refresh 方法分析


Spring 容器创建过程主要就是调用 refresh()  方法。我们先一起看看 refresh() 方法具体做了哪些事。具体分为一下几个步骤:


  1. prepareRefresh 预刷新方法,主要是用来初始化和读取上下文配置信息;


  1. obtainFreshBeanFactory() 创建 BeanFactory 对象,其实就是创建一个 Bean 工厂;


  1. prepareBeanFactory(beanFactory) 配置 Bean 工厂,比如设置 ClassLoader、BeanPostProcessor 等;


  1. postProcessBeanFactory 允许子类进行拓展;


  1. invokeBeanFactoryPostProcessors 实例化并调用所有已注册的 BeanFactoryPostProcessor 。调用 BeanFactoryPostProcessor 需要按照顺序调用,优先级是a. 实现 _PriorityOrdered_ 接口;b. 实现 Order 接口; c. 默认。


  1. registerBeanPostProcessors 注册 Bean 对象的 BeanPostProcessors


  1. initMessageSource 初始化 messageSource 其实就是为了支持国际化;


  1. initApplicationEventMulticaster 初始化事件发布器;


  1. onRefresh 模板方法,可以给子类实现,以完成特殊的处理


  1. registerListeners 注册事件监听器,Spring 中的事件机制,其实就是一个典型的观察者模式,这里其实就是注册观察者。


  1. finishBeanFactoryInitialization 完成初始化单实例的非懒加载的 Bean 对象,这里非常关键,对于 Bean 的初始化,属性填充,Aop 等都可以跟着这个方法找到。


  1. finishRefresh完成初始化,这里会发布一个 ContextRefreshedEvent 容器初始化完成事件,以及做一些其他的处理。


对这个过程我们又一个大概的了解过后,我们再来看看 refresh() 方法的定义:


public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
        // Prepare this context for refreshing.
        prepareRefresh();
        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);
        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);
            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();
            // Initialize message source for this context.
            initMessageSource();
            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();
            // Initialize other special beans in specific context subclasses.
            onRefresh();
            // Check for listener beans and register them.
            registerListeners();
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
            // Last step: publish corresponding event.
            finishRefresh();
        }
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }
            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();
            // Reset 'active' flag.
            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();
        }
    }
}


参考文档




相关文章
|
6天前
|
Java 应用服务中间件 Nacos
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
39 0
|
6天前
|
监控 Java 应用服务中间件
Spring Boot 源码面试知识点
【5月更文挑战第12天】Spring Boot 是一个强大且广泛使用的框架,旨在简化 Spring 应用程序的开发过程。深入了解 Spring Boot 的源码,有助于开发者更好地使用和定制这个框架。以下是一些关键的知识点:
25 6
|
6天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
32 3
|
6天前
|
Cloud Native Linux 开发者
【Docker】Docker:解析容器化技术的利器与在Linux中的关键作用
【Docker】Docker:解析容器化技术的利器与在Linux中的关键作用
|
6天前
|
存储 Rust 监控
EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文
本文介绍了IgH EtherCAT Master整体运行原理
37 0
EtherCAT主站IgH解析(一)--主站初始化、状态机与EtherCAT报文
|
6天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
17 1
|
6天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
108 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
6天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
|
6天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
6天前
|
存储 算法 程序员
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
C++从入门到精通:2.2.1标准库与STL容器算法深度解析

推荐镜像

更多