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

简介: 本文主要是讲 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();
        }
    }
}


参考文档




相关文章
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1386 29
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
556 4
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
负载均衡 JavaScript 前端开发
分片上传技术全解析:原理、优势与应用(含简单实现源码)
分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
XML Java 数据格式
Spring IoC容器初始化过程(xml形式)
Spring IoC容器初始化过程(xml形式)
307 0
|
XML Java 数据格式
Spring5源码(15)-IoC容器启动过程简析及XmlBeanFactory初始化
Spring5源码(15)-IoC容器启动过程简析及XmlBeanFactory初始化
264 1
|
XML 设计模式 Java
「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程
「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程
307 0
「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程
|
XML Java 数据格式
Spring源码阅读-IOC容器初始化过程
Spring IOC容器的初始化过程:Resource定位,BeanDefinition载入,向IOC容器注册BeanDefinition。整个过程由refresh()方法触发,三个过程由不同的模块完成,使用户更加灵活的对这三个过程剪裁和扩展。
494 0
|
XML JavaScript Java
Spring IoC容器初始化过程(xml形式)
Resource是Spring中用于封装I/O操作的接口,在创建Spring的容器的时候,会根据xml对应配置的类型,加载不同的数据类型
157 0
|
XML Java 测试技术
面试官:说说Spring IoC容器初始化主体流程
一、Spring IoC的容器体系 IoC容器是Spring的核心模块,是抽象了对象管理、依赖关系管理的框架解决方案。Spring 提供了很多的容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器 必须遵从的一套原则,具体的容器实现可以增加额外的功能,比如我们常用到的ApplicationContext,其下更具体的实现如 ClassPathXmlApplicationContext 包含了解析 xml 等一系列的内容, AnnotationConfigApplicationContext 则是包含了注解解析等一系列的内容。
面试官:说说Spring IoC容器初始化主体流程

推荐镜像

更多
  • DNS