【俯瞰Spring】一、Spring核心工作机制


一、前言

提起Spring,Java程序员应该不会陌生,或多或少都在企业项目中应用到Spring这个开发框架。Spring的提供Ioc、Aop等功能极大降低了软件开发的复杂性,简直就是Java程序员的福音。楼主作为一个有追(弱)求(鸡)的程序员,自恃已熟练使用Spring的各种特性,但心里总好奇,这么牛叉的框架其内部到底是怎样的工作机制。如果你也有这样的好奇,那么就跟着楼主一起来探究Spring的源码吧。

虽然Spring源码博大精深,但也是有方法可寻去看懂吃透。放心,此篇文章楼主不打算贴源码!因为一上来就直面源码,估计会让一部分人刚刚燃起看源码的信心受挫。另一方面,也容易过早陷入源码的细节泥沼中,导致一叶障目不见泰山。

毛爷爷有句名言:战略上藐视敌人,战术上重视敌人。学习Spring也应这样,内心就是要从八万米高空俯瞰、藐视它。不要怕,本文也即【俯瞰Spring】系列的开篇,楼主会带着大家尝试在心中建立一个Spring核心运行机制的大局观,先全盘后局部。话不多说,开始我们Spring俯瞰之旅吧!


二、Spring核心运行机制

2.1 一图看穿Spring

Spring是一个轻量级控制反转和面向切面编程的容器框架,其轻量级体现在Spring的IOC和AOP操作的对象就是普通的JavaBean对象。不知大家思考过没,我们平时new出来的Java对象和Spring的Bean对象,二者的区别是什么?一个普通的Java对象,Spring到底对它做了什么道德的沦丧和人性的扭曲,最终就变成具有魔力的Spring Bean?

一图胜千言,带着上面的疑惑,开始吧!
在这里插入图片描述
这幅图非常重要!这幅图非常重要!这幅图非常重要!三遍已说,容我来慢慢展开。如图所示,有A、B、C三个Java对象,首先Java虚拟机会把这三个对象加载到内存,接着轮到Spring出场。Spring通过包扫描机制,找到了classpath下面的A、B、C三个Java对象。再接着解析得到对应的三个bean定义,并存放入BeanFacory的beanDefinitionMap这个map中,同时将bean的名字记录下来存到beanDefinitionNames列表中

2.2 BeanDefinition 和BeanFactoryPostProcess

BeanDefinition 可以说是Spring最重要的数据结构没有之一,它本身就是一个POJO对象,这里暂不做详情界面。下图列举出了其大部分属性(有颜色标识的,是Spring高阶用法中常用的)。这里先关注最重要的一个属性beanClass,它决定了最终生成的Bean是哪种类型。
在这里插入图片描述
有了以上认识,就可以聊聊Spring第一个比较重要的扩展机制: BeanFactoryPostProcess,这家伙可用来修改BeanDefinition。比如在上图中,单独对C这个Java对象的bean定义进行了修改(假设把beanClass由C修改成了D),后续Spring遍历beanDefinitionNames,逐个实例化、初始化生成对应Bean对象时,由于C的bean定义修改了,生成的Bean对象的类型会为D,简直是偷天换日啊。

PS: 在真实应用中,通常不会去修改BeanDefinition的beanClass

这里推导出一个结论:Java对象和Spring生成的Bean可以说没有直接关系,上面的C对象最终生成D Bean可以佐证!

2.3 BeanPostProcess

回到第一幅图,各种BeanDefinition存放到BeanFactory中之后,Spring会遍历beanDefinitionNames,逐个触发getBean()方法,进行实例化。所谓实例化,就是利用反射机制new出对象,通常是利用对象的无参构造。注意,这里new出来的对象,还是一个裸对象,是没有依赖注入的。

有了new出来的对象后,通过解析这个对象的依赖关系,就开始执行依赖注入、初始化。这一过程中,就涉及到Spring最重要的扩展机制: BeanPostProcess,俗称Bean的后置处理器,绝对算Spring核心类,依赖注入和Aop就是通过BeanPostProcess实现的。

走完这一步,就算真正完成了一个Java对象到Spring Bean的蜕变。回答最开始的疑问,Spring Bean和Java对象的区别就是,Java对象需要程序员去new出来,而Spring Bean是由Spring自己new出来,交由Spring管理并自动执行了依赖注入、初始化,具备完整生命周期。


三、总结

3.1 小结

1、Spring的核心运行机制概括起来就三步,先记住这三步,做到心中有丘壑,后续按图索骥再细扣每一步,相信能更快上手Spring源码

  • Step1: 找到需要交给Spring管理的Java对象;
  • Step2: 解析Java对象得到Bean定义;
  • Step3: 遍历Bean定义,进行实例化、初始化,得到最终产物Bean对象

2、记住三个核心类:

  • BeanDefinitionBeanFactoryPostProcess;后者是Spring用来修改BeanDefinition的扩展机制
  • BeanPostProcess: 用来完成依赖注入、实现Aop等

3.2 其它

Spring如何做包扫描、如何解析Bean定义、解析出的Bean定义放在哪里、何处触发了getBean()、Spring的实例化、初始化做了什么、Spring的BeanPostProcess如何做Aop?这些重要知识点本文都未交待,后续会开展专题逐一击破,敬请关注!


万事开头难,俯瞰Spring系列第一篇总算憋出来了!19年楼主重新拾起《Spring源码深度解析》,几次一股脑扎进Spring源码,耐着性子不停Debug,还是始终不得心法,内心是崩溃的!还好,最终跌跌撞撞摸到门道,这篇文章就是楼主经验的一个小结,希望对Spring源码学习者有所帮助!

发布了27 篇原创文章 · 获赞 4 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/caiguoxiong0101/article/details/104583042
今日推荐