Spring IoC源码学习:obtainFreshBeanFactory 详解

本文详细剖析了Spring IoC的`obtainFreshBeanFactory`方法,阐述了该方法如何解析配置文件,加载BeanDefinition到BeanFactory的过程,涉及refreshBeanFactory、loadBeanDefinitions等多个关键步骤,解释了bean定义加载到BeanFactory中的三个缓存。内容适合Spring源码学习者和面试准备者。
摘要由CSDN通过智能技术生成

微信搜索【程序员囧辉】,关注这个坚持分享技术干货的程序员。

目录

Spring IoC源码学习全系列

前言

obtainFreshBeanFactory 方法概述

正文

代码块1:refreshBeanFactory 方法

代码块2:loadBeanDefinitions

代码块3:loadBeanDefinitions

代码块4:loadBeanDefinitions

代码块5:loadBeanDefinitions

方法块6:loadBeanDefinitions

代码块7:doLoadBeanDefinitions

代码块8:doLoadDocument

代码块9:registerBeanDefinitions

代码块10:createReaderContext

代码块11:registerBeanDefinitions

代码块12:doRegisterBeanDefinitions

代码块13

代码块14:parseBeanDefinitions

总结

相关文章


Spring IoC源码学习全系列

小白也看得懂的 Spring IoC 核心流程介绍

Spring IoC源码学习:总览

Spring IoC源码学习:ApplicationContext 刷新前的配置

Spring IoC源码学习:obtainFreshBeanFactory详解

Spring IoC源码学习:parseDefaultElement详解

Spring IoC源码学习:parseCustomElement详解

Spring IoC源码学习:context:component-scan 节点详解

Spring IoC源码学习:invokeBeanFactoryPostProcessors详解

Spring IoC源码学习:registerBeanPostProcessors详解

Spring IoC源码学习:finishBeanFactoryInitialization详解

Spring IoC源码学习:getBean详解

Spring IoC源码学习:createBean详解(上)

Spring IoC源码学习:createBean详解(下)

Spring IoC源码学习:@Autowire 详解

Spring IoC源码学习:finishRefresh 详解

 

前言

上文 Spring IoC:ApplicationContext 刷新前的配置 介绍了 refresh 方法前的环境准备操作,接下来正式进入 refresh 方法。prepareRefresh 是refresh 里的第一个方法,主要是一些准备工作,比较简单的方法,看一下就了解了。接下来是 obtainFreshBeanFactory 方法,该方法用于获得一个新的 BeanFactory,本文将详细介绍该方法。

 

obtainFreshBeanFactory 方法概述

该方法会解析所有 Spring 配置文件(通常我们会放在 resources 目录下),将所有 Spring 配置文件中的 bean 定义封装成 BeanDefinition,加载到 BeanFactory 中。常见的,如果解析到<context:component-scan base-package="" /> 注解时,会扫描 base-package 指定的目录,将该目录下使用指定注解(@Controller、@Service、@Component、@Repository)的 bean 定义也同样封装成 BeanDefinition,加载到 BeanFactory 中。
上面提到的 “加载到 BeanFactory 中” 的内容主要指的是添加到以下3个缓存:

  • beanDefinitionNames缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 集合。
  • beanDefinitionMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和 BeanDefinition 映射。
  • aliasMap缓存:所有被加载到 BeanFactory 中的 bean 的 beanName 和别名映射。

 

正文

首先,我们来到 obtainFreshBeanFactory 方法。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 1.刷新 BeanFactory,由AbstractRefreshableApplicationContext实现
    refreshBeanFactory();
    // 2.拿到刷新后的 BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (logger.isDebugEnabled()) {
        logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    }
    return beanFactory;
}

1.刷新 BeanFactory,由 AbstractRefreshableApplicationContext 实现,见代码块1详解

 

代码块1:refreshBeanFactory 方法

@Override
protected final void refreshBeanFactory() throws BeansException {
    // 1.判断是否已经存在 BeanFactory,如果存在则先销毁、关闭该 BeanFactory
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 2.创建一个新的BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        // 3.加载 bean 定义。
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    } catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

3.加载 bean 定义,由 XmlWebApplicationContext 实现,见代码块2详解

 

代码块2:loadBeanDefinitions

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    // 1.为指定BeanFactory创建XmlBeanDefinitionReader
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

    // Configure the bean definition reader with this context's
    // resource loading environment.
    // 2.使用此上下文的资源加载环境配置 XmlBeanDefinitionReader
    beanDefinitionReader.setEnvironment(getEnvironment());
    // resourceLoader赋值为XmlWebApplicationContext
    beanDefini
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员囧辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值