Spring IOC 源码解读

这篇具有很好参考价值的文章主要介绍了Spring IOC 源码解读。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

将回答以下问题:

  1. BeanFactory 和 ApplicationContext 之间的关系和区别。
  2. 一个 Bean 是如何被注入到 IOC 容器里,中间经历了什么过程(Bean 的生命周期)。

先入为主

假设你已经有如下经验:

  • 什么是 IOC。
don‘t call us, we‘ll call you - 好莱坞原则
  • 依赖查找和依赖注入。
依赖查找是 IOC 容器中的对象通过容器提供的 API 主动获取依赖对象
依赖注入是 IOC 容器将依赖对象直接注入到被依赖对象中
都是 IOC 容器实现的方式
  • Spring framework 的使用经验。

源码版本

5.3.8

涉及到的 Spring 模块

  • spring-context
  • spring-bean
  • spring-core

ApplicationContext 和 BeanFactory

Spring IOC 源码解读

 https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-introduction

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using the BeanFactory instead of the ApplicationContext, see The BeanFactory.

  • 两者都是 IOC容器。
  • ApplicationContext 继承自 BeanFactory,同时内部还组合了一个 BeanFactory 的实现(DefaultListableBeanFactory)。
org.springframework.context.support.AbstractApplicationContext#getBeanFactory

Spring IOC 源码解读

  • BeanFactory 提供了最基础的 IOC 容器功能,例如:依赖查找。
  • ApplicationContext 是 BeanFactory 的超集,除了拥有 BeanFactory 的能力之外,还提供:
    • AOP
    • 资源管理
    • 国际化
    • 事件
    • Environment 抽象
  • BeanFactory 只会在查找 Bean 时才去创建(实例化,初始化)Bean,ApplicationContext 在启动时就已经创建好所有的 Bean。
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

Spring IOC 源码解读

Bean 生命周期

1. 启动 spring 应用上下文

org.springframework.context.support.ClassPathXmlApplicationContext

AbstractApplicationContext#refresh

  • 创建并初始化一个内部的 BeanFactory(DefaultListableBeanFactory)
  • AbstractRefreshableApplicationContext#refreshBeanFactory

2. 加载Bean元信息

Bean 定义中的 id,name,scope,primary 等统称为 Bean 元信息
org.springframework.beans.factory.config.BeanDefinition

AbStractXmlApplicationContext#loadBeanDefinitions

AbstractBeanDefinitionReader#loadBeanDefinitions

XmlBeanDefinitionReader#loadBeanDefinitions

2.1 解析 BeanDefinition

DefaultBeanDefinitionDocumentReader#parseBeanDefinitions

DefaultBeanDefinitionDocumentReader#processBeanDefinition

解析 xml 构建 BeanDefinitionHolder

BeanDefinitionHolder 包含 beanName,aliaes,BeanDefinition

默认 beanName = id。如果没有指定 id,容器会为 Bean 创建一个唯一的 beanName

问题:容器创建的唯一的 beanName 的规则是怎样的。

org.springframework.beans.factory.support.DefaultBeanNameGenerator#generateBeanName

2.2 注册 BeanDefinition 到 BeanFactory

DefaultListableBeanFactory#registerBeanDefinition

beanDefinitionMap(ConcurrentHashMap) 维护 BeanName 和 BeanDefinition 的对应关系

beanDefinitionNames(ArrayList) 保证 Bean 注册的顺序

2.3 合并 BeanDefinition

AbstractBeanFactory#getMergedLocalBeanDefinition

继承配置

最终所有的 BeanDefinition 都会被构建成 RootBeanDefinition

3. Bean 实例化

AbstractApplicationContext#finishBeanFactoryInitialization

DefaultListableBeanFactory#preInstantiateSingletons

AbstractBeanFactory#getBean

DefaultSingletonBeanRegistry#getSingleton

AbstractAutowireCapableBeanFactory#createBean

3.1 Bean Class 加载

AbstractBeanFactory#resolveBeanClass

AbstactBeanDefinition#resolveBeanClass

BeanDefinition 中的 beanClass(Object) 是以 String 定义,通过 spring 的 ClassUtil.forName 处理成 Class 类型,并通过 ClassLoader 加载

3.2 实例化前阶段

AbstractAutowireCapableBeanFactory#createBean

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

如果实现并注册了 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 会触发回调

3.3 实例化阶段

AbstractAutowireCapableBeanFactory#doCreateBean

AbstractAutowireCapableBeanFactory#createBeanInstance

  • 如果 BeanDefinition 中指定了工厂方法(factory-method) 则通过工厂方法AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod
  • 如果 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 指定了构造器,或 BeanDefinition 中的 autowire-mode 为 constructor,或 BeanDefinition 中指定了构造参数(constructor-arg),或 BeanFactory#getBean 方法传了构造参数。则通过 AbstractAutowireCapableBeanFactory#autowireConstructor
  • 默认使用无参构造器,创建的实例会被包装成 BeanWrapper,BeanWrapper 中的 wrappedObject 就是最终会被注入到 IOC 容器中的 Bean。

问题:autowire-mode = constructor 时,构造器中的构造参数的注入是 byType ,还是byName。

DefaultListableBeanFactory#doResolveDependency

DefaultListableBeanFactory#determineAutowireCandidate

注意是否有 primary = ture 的 Bean

3.4 实例化后阶段

AbstractAutowireCapableBeanFactory#populateBean

如果实现并注册了 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 会触发回调

此时 Bean 已经完成实例化,但是并未填充属性

4. Bean 属性填充

BeanDefinition 中包含 Bean 的属性列表(org.springframework.beans.PropertyValues)
Bean 的属性会被构建成 org.springframework.beans.PropertyValue

AbstractAutowireCapableBeanFactory#populateBean

4.1 填充前阶段

如果实现并注册了 InstantiationAwareBeanPostProcessor#postProcessProperties 会触发回调

此阶段可以对 PropertyValue 做修改

4.2 构建属性描述

java.beans.PropertyDescriptor

包含属性的读方法引用(readMethodRef,通常是getter),写方法引用(writeMethodRef,通常是setter)等信息

AbstractAutowireCapableBeanFactory#filterPropertyDescriptorsForDependencyCheck

BeanWrapper#getPropertyDescriptors

java.beans.Introspector#getTargetPropertyInfo

过滤出所有有读方法和写方法的属性。

构建完成的 PropertyDescriptor 会作为 BeanWrapper 的属性。

4.3 填充属性值

AbstractAutowireCapableBeanFactory#applyPropertyValues

4.3.1 属性值类型转换

  • BeanDefinitionValueResolver#resolveValueIfNecessary,获取 BeanDefinition 中定义的属性值。
  • AbstractAutowireCapableBeanFactory#convertForPropertyBeanWrapperImpl#convertForProperty
  • 根据 PropertyDescriptor 中的读方法引用和写方法引用,通过反射获取转换目标类型,目标类型会被构建成 org.springframework.core.convert.TypeDescriptor。
  • 经过转换后的属性值,会记录在 PropertyDescriptor 的 convertedValue 属性中。

问题:获取到的转换目标类型是 getter 的返回类型,还是 setter 的参数类型。

org.springframework.core.convert.Property#resolveMethodParameter

4.3.2 调用 Bean 属性的 writeMethod 赋值

org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue

5. Bean 初始化

AbstractAutowireCapableBeanFactory#initializeBean

5.1 初始化前阶段

Aware 接口回调

org.springframework.beans.factory.BeanNameAware

org.springframework.beans.factory.BeanClassLoaderAware

org.springframework.beans.factory.BeanFactoryAware

org.springframework.context.EnvironmentAware

org.springframework.context.EmbeddedValueResolverAware

org.springframework.context.ResourceLoaderAware

org.springframework.context.ApplicationEventPublisherAware

org.springframework.context.MessageSourceAware

org.springframework.context.ApplicationContextAware

org.springframework.context.ApplicationStartupAware

AbstractAutowireCapableBeanFactory#invokeAwareMethods

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

如果实现并注册了 BeanPostProcessor#postProcessBeforeInitialization 会触发回调

5.2 初始化阶段

AbstractAutowireCapableBeanFactory#invokeInitMethods

  • 如果实现了 org.springframework.beans.factory.InitializingBean 接口,会回调 InitializingBean#afterPropertiesSet
  • 如果 BeanDefinition 中有自定义初始化方法(init-method),会回调自定义初始化方法

AbstractAutowireCapableBeanFactory#invokeCustomInitMethod

5.3 初始化后阶段

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

如果实现并注册了 BeanPostProcessor#postProcessAfterInitialization 会触发回调

6. 注册 Bean(singleton) 到 IOC 容器中

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonObjects

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registeredSingletons

DefaultSingletonBeanRegistry#addSingleton

问题:spring 是如何解决循环依赖问题。

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)文章来源地址https://www.toymoban.com/news/detail-431755.html

到了这里,关于Spring IOC 源码解读的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度解析 Spring 源码:揭秘BeanFactory 之谜

    1.1 BeanFactory的概述 BeanFactory是Spring框架中的一个核心接口,它提供了一种灵活的方式来管理Bean,并实现了IoC(控制反转)和DI(依赖注入)等特性,为应用程序提供了灵活、可扩展的对象管理和配置机制。 BeanFactory的特性 : IoC容器: BeanFactory是Spring的IoC容器之一。IoC是一种

    2024年04月26日
    浏览(29)
  • 【Spring源码】 BeanFactory和FactoryBean是什么?

    面试官:“看过Spring源码吧,简单说说Spring中BeanFactory和FactoryBean的区别是什么?” 大神仙:“BeanFactory是bean工厂,FactoryBean是工厂bean”。 这么回答,等于面试官问你Spring是什么,你回答这个单词翻译叫春天。 首先看下C知道(ChitGPT)的回答 没错,基本上已经给出了答案。

    2023年04月19日
    浏览(30)
  • Spring源码笔记之SpringIOC--(3)什么是BeanFactory?

    什么是BeanFactory? BeanFactory 是SpringIOC的最顶层接口,涵盖了IOC容器最基本的操作。 ListableBeanFactory 、 ConfigurableBeanFactory 提供了IOC容器获取所有Bean、配置Bean的额外能力。所有 BeanFactory 的实现类持有所有Bean的定义 BeanDefinition ,用一个唯一的字符串(即Bean的名字)区分。 Bean

    2024年02月20日
    浏览(28)
  • Spring IOC 源码分析

    ​ IoC (Inversion of control ) 控制反转。它是一种思想不是一个技术实现。描述的是: Java 开发领域对象的创建以及管理的问题。 例如:现有类 A 依赖于类 B 。传统的开发方式 :往往是在类 A 中手动通过 new 来 new 一个 B 的对象出来使用 IoC 思想的开发方式 :不通过 ne

    2024年02月02日
    浏览(30)
  • Spring复习-问题回答

    1.什么是 spring,你对 spring 的理解? Spring是一个轻量级,非侵入式的(不使用框架特定的类,感受不到框架) IOC和AOP 一站式的java后端开发框架,简化企业开发。 2.spring 的优缺点 优点: Spring是一个容器,可以管理对象(IOC); 创建对象和使用对象分离,降低耦合度; 使用

    2024年01月24日
    浏览(23)
  • Spring源码解析——IOC属性填充

    正文 doCreateBean() 主要用于完成 bean 的创建和初始化工作,我们可以将其分为四个过程: 最全面的Java面试网站 createBeanInstance() 实例化 bean populateBean() 属性填充 循环依赖的处理 initializeBean() 初始化 bean 第一个过程实例化 bean在前面一篇博客中已经分析完了,这篇博客开始分析

    2024年02月08日
    浏览(28)
  • Spring源码解析——IOC之循环依赖处理

    循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图所示: 注意,这里不是函数的循环调用,是对象的相互依赖关系。循环调用其实就是一个死循环,除非有终结条件。 最全面的Java面试网站

    2024年02月08日
    浏览(35)
  • 【框架源码】手写Spring框架IOC容器核心流程

    要是想要了解Spring IOC底层,首先我们就得先了解什么是IOC。 IOC就是控制反转,把对象创建和对象之间的调用过程交给Spring进行管理。 使用IOC目的就是之前我们创建对象的方式都是用new的方式创建,这个方式有个缺点,被创建对象的类的位置一旦被改动,new就会报错,类与类

    2024年02月06日
    浏览(45)
  • 深入分析Spring的IoC容器:从底层源码探索

    前言: 博主在最近的几次面试中,大中小厂都问到了Spring的ioc容器相关问题,这块知识确实是面试中的重点内容,因此结合所看的书籍,在这篇文章中总结下。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读,感谢大佬的关注。 如果文章有什么需要改进的地方欢迎

    2024年02月12日
    浏览(40)
  • 【spring源码系列-02】通过refresh方法剖析IOC的整体流程

    Spring源码系列整体栏目 内容 链接地址 【一】spring源码整体概述 https://blog.csdn.net/zhenghuishengq/article/details/130940885 【二】通过refresh方法剖析IOC的整体流程 https://blog.csdn.net/zhenghuishengq/article/details/131003428 【三】xml配置文件启动spring时refresh的前置工作 https://blog.csdn.net/zhenghuishen

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包