spring源码之美<三>:从IOC概念入手学习Spring

前言

spring源码里面包含了很多的模块,也提供了很多功能,如果去一一叙述这些模块及其对应的功能,必然会是长篇大论,我个人比较讨厌一开始就去介绍所有的模块的功能,虽然能够让我了解整体的项目结构,但是读的时候却稍显枯燥,所以我决定跳过最基础也是最常见的模块的概览部分,直接进入源码的学习。

从哪儿开始入手学习spring的源码呢?

在我刚接触spring的时候,就不可避免的接触到了两个词汇---IOC和AOP,几乎每一本教材,每一篇blog都会反复的提到这两个词,阐述其意义,其重要性。

讲道理的话,在刚开始学习spring的时候,我不是很明白这两个词汇的意义,感觉很抽象,理解起来很片面,总感觉抓不到核心的地方,后来随着对spring使用的增多,才慢慢的理解了IOC和AOP的意义。 现在想想,在那时候,IOC和AOP真是我学习spring的一道坎。

所以我觉得学习spring还是从这两个词汇入手吧,毕竟从哪摔倒从哪爬起来不是。

先学会IOC和AOP相关的知识,这样由理解核心实现入手,然后再抽丝剥茧的学会他们外层的技术,应该会容易很多吧?

Spring官方文档

该文档记录了spring框架的核心技术实现,参考该文档,可以更快的理解spring核心技术。

Spring IOC概念的简单理解

对于spring框架来说IOC无疑是其最核心的技术之一,他改变了我们创建实例时的过程和思维,提供了一种全新的实例创建过程。 在不使用IOC的前提下,我们创建一个对象实例,通常都会手动的new出该对象实例,之后再根据需要去设值其依赖的对象,这是一种比较常见的方式,我们维护着整个对象实例的生命周期,我们自己负责对象实例的创建,同时我们也自己维护着对象之间的依赖关系等一系列操作。(PS:虽然对象的销毁掌握在GC手里,但是我们依然可以很明确的知道对象在何时就开始进入清理倒计时。)

而对于spring IOC来讲,他会维护一个容器,容器持有所有对象的引用以及对象之间的依赖关系 ,当我们需要使用一个对象的时候 ,直接从容器中拿出来该对象使用就可以了,容器会帮助我们完成对象的创建,对象实例之间依赖的创建。

这两者有一个很明显的区别就在于:常规方式下,我们几乎手动维护了整个对象实例的生命周期,在整个过程中我们需要自己手动组装我们需要的对象实例,而在使用spring IOC的前提下,我们仅仅只需要告诉容器对象之间的依赖关系,spring就会帮助我们完成包括组装对象在内的一系列操作。

前者,就好比我们自己买食材自己做饭,而后者更像我们去饭店点菜吃饭,一个亲力亲为,一个坐等享受~

为什么要从ClassPathXmlApplicationContext类入手。

通过前面关于spring IOC概念的叙述中,我们不难理解,spring IOC技术的实现依赖与一个维护了所有对象及其依赖关系的容器,那么这个容器是什么呢?

spring源码中有一个最基础的类叫做BeanFactory,该类提供了一个能够管理任意类型对象的高级配置机制,而该类也恰好就是我们入手学习spring源码的一条线索,但是我们在实际使用spring的过程中几乎很少会使用到BeanFactory,反而其子实现ApplicationContext使用的更多,这是因为BeanFactory仅仅只定义了容器的基础功能,而ApplicationContext在基于BeanFactory定义的功能基础上实现了更多的功能,所以一方面ApplicationContextBeanFactory的实现类,另一方面ApplicationContext也是BeanFactory的超集。

如果从ApplicationContext入手学习,我们不得不又接触另一个叫做ClassPathXmlApplicationContext的类,该类是在初学spring时候就会接触到的一个类,它实现了加载XML文件来初始化Spring容器的能力。

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext('{{Spring XML配置文件}}');

和其实现类似功能的类还有很多,比如:FileSystemXmlApplicationContextAnnotationConfigWebApplicationContext

但是因为相对来说,接触更多的是ClassPathXmlApplicationContext,通常我们也会使用该类作为我们使用spring项目的入口。

就像我们调试代码要从main方法开始一样,调试spring也就从该类开始吧~

初识ClassPathXmlApplicatioContext

ClassPathXmlApplicationContextt类位于spring-context项目org.springframework.context.support包下。

在整个源码调试过程中,默认使用IntelliJ IDEA工具。

我们在IDE工具内打开该类, ClassPathXmlApplicationContext

之后输入快捷键ctrl+alt+u打开该类的UML图,可以看到其中大概涉及了二三十个类或接口,其中就有我们刚才提到的BeanFactory接口以及ApplicationContext接口 ClassPathXmlApplicationContextUML

点击查看UML大图

万事开头难,既然找到了入口,接下来的任务就是根据类图,从顶层开始大概了解涉及到的类和接口的作用。

BeanFactory

BeanFactory接口是整个spring容器的底层接口,他定义了在spring中作为一个bean容器需要提供的基本功能——管理Bean定义。

这里有一个好玩的问题,什么是Bean?Bean定义又是什么?

bean以及bean定义的概念

简单的理解bean其实就是java对象,是在spring容器中对java对象的一个称谓,就好像二狗在学校被称为学生一样,二狗还是那个二狗,只不过他多了一个学生的称号,那是不是其他人也能成为学生呢?当然可以,前提是这些人通过入学考试,对于Spring bean也是一样的,java对象还是那个java对象,只不过当他被spring管理之后它就多了bean的称号。

那么什么是Bean定义呢,这里还是要说一下二狗哥,二狗哥进了学校之后,招生办的人就给二狗哥搞了个学籍,学籍里面详细记录了二狗哥作为学生所需的所有数据,什么姓名啊,性别啊,品种(。。呸。。这个不算),年龄啊之类的。这个学籍以后就是二狗哥学生身份的依据了,以后学校就根据这个学籍来管理二狗哥。

一样的道理,当一个java对象被spring容器管理之后,spring会根据这个对象生成一个bean定义,这个bean定义里面了包含了描述bean对象的元数据,emmm...也就是说用来描述bean对象的元数据构成了bean定义。

BeanFactory的概念

在spring中,BeanFactory通常被认为是所有bean的注册中心,它集中进行bean定义的维护和管理操作,因此,BeanFactory也就不可避免的需要维护大量的bean定义,根据常识:

在现实生活中,当需要管理大量同类型实体的时候,我们都会为这些实体提供一个能够识别该实体的唯一标识,比如:中国公民的身份证号,汽车的车牌号等。

对于spring容器来说,道理是一样的道理,spring给所有受spring管理的bean都会生成一个容器内唯一的String类型的唯一标识,并将会根据该标识对bean定义进行维护和管理。

BeanFactory的源码解析

BeanFactory位于spring-beans模块下的org.springframework.beans.factory包内,

查看BeanFactory的中文注释版源码

查看BeanFactory的英文原版注释源码

BeanFactory中定义了13个方法,1一个常量,其大致作用如下图:

Bean Factory源码概览

其中常量FACTORY_BEAN_PREFIX涉及到了一个叫做FactoryBean的概念,简单的来说FactoryBean就是spring对工厂模式的一种通用实现,通过实现FactoryBean来实现工厂模式的Bean,会被spring容器特殊处理,这里先提出来,后续再继续深入。

转载于:https://my.oschina.net/u/3101282/blog/1844300

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值