16 张图解锁 Spring 的整体脉络(上)

举报
龙哥手记 发表于 2022/11/21 22:40:04 2022/11/21
【摘要】 《读尽源码 第二十一篇》

印象中的 Spring

脑海中有这么一条公式:

👉 IOC = 工厂模式 + XML + 反射

👉 而 DI , AOP , 事务 等也都在 XML 中很直观的表现出来

虽然我们现在大部分用这个注解来代替,但是原理还是基本一样的 🐖

注解使用起来很方便,但是学习的话,还是建议先通过这个 XML ,毕竟结构性的文档,有层次感,可以留下更深的印象~ 😄

小小 Spring

把 Spring 浓缩一下,就有了这么一点小东西 🐖

image-20211213224920994

想了下,我们用 Spring ,其中最主要的一点,就是用它来帮我们管理,创建这个 Bean 。

那么先从源头看起 —— Bean 从哪来 (@_@;)

Bean 解析流程

image-20211213225044814

如图所示,就是通过 解析器,对我们的 XML 文件或者注解进行解析,最后将这些信息封装在 BeanDefinition 类中,并通过 BeanDefinitionRegistry 接口将这些信息 注册 起来,放在 beanDefinitionMap 变量中, key : beanName , value :BeanDefinition 。

简单看看 BeanDefinition 中的属性叭

BeanDefinition

  • beanClass : bean 的类型 ,实例化时用的 🐖

  • scope : 作用范围有 singleton,prototype

  • isLazy : 懒加载 ,true 的话 会在 getBean 时生成,而且 scope 的 prototype 无效,false 在 Spring 启动过程中直接生成

  • initMethodName : 初始化方法,当然是初始化时调用 🐖

  • primary : 主要的,有多个 Bean 时使用它

  • dependsOn : 依赖的 Bean,必须等依赖 Bean 创建好才可以创建

PS: @Component ,@Bean , 都会被解析成 BeanDefinition

反射

有了原料后呢,咋们再来看看这个 工厂 BeanFactory

先简单想一想这个工厂要怎么创建这个 Bean 呢?

没错,肯定就是这个 反射 啦 😄

那么,结合我们从原料中获取的重要属性之一的 beanClass ,我们可以画出这么一张图 👇

image-20211213225124831

那么我们再来看看这个 BeanFactory 叭 😄

BeanFactory

先来看看 作为 IOC 容器的根接口 的 BeanFactory 提供了什么方法吧 👇

image-20210904162844126

主要是这个 getBean 方法,以及 别名获取,类型获取 方法和其他一些判断方法如 :单例,多例,类型匹配,包含 bean

我们来简单看看它的子接口都有哪些叭~😄

这里分享个小技巧叭 🐖

看源码的时候,一般就直接看这个默认接口 如这里的 DefaultListableBeanFactory

image-20210904161436139

基本上看个类名就知道大概作用了,那么先对号入座下 👇

ListableBeanFactory

👉 遍历 bean

HierarchicalBeanFactory

👉 提供 父子关系,可以获取上一级的 BeanFactory

ConfigurableBeanFactory

👉 实现了 SingletonBeanRegistry ,主要是 单例 Bean 的注册,生成

AutowireCapableBeanFactory

👉 和自动装配有关的

AbstractBeanFactory

👉 单例缓存,以及 FactoryBean 相关的

ConfigurableListableBeanFactory

👉 预实例化单例 Bean,分析,修改 BeanDefinition

AbstractAutowireCapableBeanFactory

👉 创建 Bean ,属性注入,实例化,调用初始化方法 等等

DefaultListableBeanFactory

👉 支持单例 Bean ,Bean 别名 ,父子 BeanFactory,Bean 类型转化 ,Bean 后置处理,FactoryBean,自动装配等

是不是非常丰富 😄

FactoryBean

FactoryBean ,它本身就是个 Bean,算是小工厂 ,归 BeanFactory 这个大工厂管理的。

image-20210904174616712

可以看到它就只有三个方法

  1. getObject() 获取对象
  2. isSingleton() 单例对象
  3. getObjectType() 返回的是 Bean 对象的类型

相比大工厂 BeanFactory 少了特别多东西,没有严格的 Bean 生命周期流程 😄

FactoryBean 对象本身也是一个 Bean,是一个小工厂,可以生产另外的 Bean

BeanFactory 是 Spring 容器的根接口,是大工厂,生产各种各样的 Bean

beanName 就是正常对象

“&”+beanName , 获取的是实现了该接口的 FactoryBean 工厂对象

大致如下 👇

image-20211213225330193

ApplicationContext

我们再来看看这个 ApplicationContext

image-20210904161808341

可以看到它扩展了很多功能,除了 BeanFactory ,它还可以创建 , 获取 Bean,以及处理国际化,事件,获取资源等

  • EnvironmentCapable 获取 环境变量 的功能,可以获取到 操作系统变量 和 JVM 环境变量
  • ListableBeanFactory 获取所有 BeanNames,判断某个 BeanName 是否存在 BeanDefinition 对象,统计 BeanDefinition 对象,获取某个类型对应的所有 beanNames 等功能
  • HierarchicalBeanFactory 获取父 BeanFactory ,判断某个 name 是否存在 bean 对象的功能
  • MessageSource 国际化功能,获取某个国际化资源
  • ApplicationEventPublisher 事件发布功能(重点)
  • ResourcePatternResolver 加载,获取资源的功能,这里的资源可能是文件,图片 等某个 URL 资源都可以

还有这三个重要的类 👇,就不一一介绍先啦 😄

  1. ClassPathXmlApplicationContext
  2. AnnotationConfigApplicationContext
  3. FileSystemXmlApplicationContext

赶紧来看看这个核心叭!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。