《Spring揭秘》读书笔记(一)

一直想认真读一本Spring源码级别解读的书,因为现在的Java程序员某程度上也是Spring程序员。
Spring已经占据了Java的生态,除了日常的Web后端开发要用到Spring。面试时候Spring也是Java程序员的一个必考察的一个点。随着现在面试官的套路越来越深,面试难度也越来越大。单纯地掌握Spring的使用是远远不够的。

现在习惯看书之前都先去豆瓣看看相关的书评,筛选一下要读的书籍。Spring源码相关的书籍,主流有三本。

Spring技术内幕
Spring源码深度解析
Spring揭秘

技术内幕这本书我当时买了第一版,评价跟网友的一致,书中太多大量的Spring源码的粘贴,极其影响阅读。内容更像是源码的解析,而且由于Spring的源码有多层的嵌套与调用,看完作者的解读也很难看懂。

源码深度解析这书,我也粗略看过。同样也是按Spring源码的流程解读,内容苦涩。

Spring揭秘的评分很高,在豆瓣技术书来说。9分是一个很高的评分。

选书完毕,接下来就是要开始研读了。

概要

全书分七个部分,分别为

  • 掀起Spring的盖头来
  • Spring的IoC容器
  • Spring AOP框架
  • 使用Spring访问数据
  • 事务管理
  • Spring的Web MVC框架
  • Spring框架对J2EE的服务集成和支持

分析一下作者的outline,前面三部分,起源,IoC,AOP 这个在意料之中。一般讲一个框架,数据库到新的技术,都会回顾一下此项技术的背景。而IoC是Spring的核心理念,AOP则是Spring的强大的功能。
其余的访问数据,事务,MVC框架,集成更偏向于使用的感觉,后续在读到的时候会再讨论。

掀起Spring的盖头来

Spring的发起人是Rod Johnson,框架的主要理念来源于他的 Expert One-On-One J2EE Development and Design。其实Spring对标的项目是EJB,当时EJB是一个比较盛行的J2EE的解决方案。但Rod Johnson觉得EJB不应该是J2EE的唯一选择,应该说Rob Johnson为了反对EJB而推出了Spring。可能当时他自己也没有想到Spring会变成Java的事实行也标准,现在的Java程序员几乎都是使用Spring进行开发。

这里提到的一个概念:POJO(Plain Old Java Object,简单Java对象),其实我们平常开发中用的VO,DTO,DO都是POJO,我的理解就是没有业务逻辑的简单Java对象,一般只有属性和对应的get set 方法构成。POJO这个概念最主要是用来跟EJB的企业Java Bean对对比,正正因为EJB中的Bean太重,太复杂,所以才衍生出POJO的概念。然后再触发Rob 的Spring构想。
《揭秘》中其余说的Spring的子项目,包括Spring Web Flow,Spring Web Services,Spring Security等众多子项目在这里就不在复述了。

第一部分只有一章,主要是引子的作用。说一说Spring的历史,也提到了Spring的由来的原因。其中对POJO的论述也是点到即止,对比《Beginning Spring》中用用POJO作为全书第一章没有说得很细。只是让读者对Spring有一个概念。

Spring的IoC容器

Spring的最核心的一个理念,就是容器。而IoC,DI也是我们在讨论Spring的时候听到最多的名词。

IoC的基本概念

这章先阐述两个定义:

  • IoC:Inversion of Control,控制反转。
  • DI: Dependency Injection,依赖注入。
    这里作者也做了一个不错的补充,控制反转依赖注入如果不是很严谨的区分可以说是看作类似的概念。利用依赖注入实现控制反转,我觉得这样的描述应该更准确。

Don't call us, we will call you.

这句好莱坞原则感觉是说到IoC的时候必定被引用一样。

这里作者用了“另一半”去比喻IoC,举的例子是:使用IoC之前,出门的时候要自己找衣服穿。使用了IoC之后,只需“一句话,一个眼神”就已让IoC帮你穿上衣服。
例子虽然比较形象生动,但有模糊了原本概念之嫌。

因为这里没有将IoC和DI的关键点,依赖关系明确说清楚。
书中原句:

通常情况下,被注入对象会直接依赖于被依赖对象

还是未能说清“依赖于对象”这件事,由此也未能很好引出“应尽量不依赖于实现,应依赖接口”的面向接口编程的原则。

细看之下,作者还针对此用了一个注释来说明。注释在图2-2下。
的确也像其他评论的同学说的,是良心之作。

此章(第2章)余下的几种注入方法:

  • 构造方法注入
  • setter方法注入
  • 接口注入
    还有这几种方式的比较,就是老生常谈了。

掌握大局的IoC Service Provider

第3章,作者先引入了标题的新概念。IoC Service Provider 即IoC服务提供者。用这个概念引出Spring中的IoC容器,BeanFactory,ApplicationContext也不失为作者的一点苦心。
个人觉得这章有两个作用

  1. 由IoC概念延展到IoC Service Provider的概念,随后延展到BeanFactory,ApplicationContext时候会更顺滑。
  2. 从侧面去引导读者去思考,一个IoC容器要做什么?我觉得这点是更加重要的,因为读源码的一个重点并不是解释,解读。而是跟源码的作者一样,去思考为什么要这样做。

IoC Service Provider 的职责

  • 业务对象的构建管理(也就是怎样构建对象,我们一般的方法是使用 new 关键字)
  • 业务对象的依赖绑定(对象之间,必然是存在依赖关系的,只有零件不组装起来,玩不转)

接下来作者给出了IoC管理对象依赖关系的秘密

  • 直接编码方式
  • 配置文件方式
  • 元数据方式
    这里不作赘述。

Spring的IoC容器之BeanFactory

这章作者在开头就给了一张图,正好衔接了上一章的IoC Service Provider的内容。

Spring IoC

从图去引出,Spring的IoC容器其实也是基于IoC Service Provider的理念上扩展。

Spring 提供的容器:

  • BeanFactory
  • ApplicationContext

BeanFactoryApplicationContext的区别,已经是很多书的“老生常谈”。包括:
BeanFactory默认懒加载,ApplicationContext扩展了BeanFactory,官方推荐的容器是ApplicationContext,还有ApplicationContext的资源获取能力,消息发送能力,支持国际化等。
在作者给出的继承关系图也可以体现到。

applicationContext

本章就要说到全书,甚至是Spring的重点 BeanFactory的原理。我自己看的时候也有会一个感觉,怕自己看不懂。因为BeanFactory涉及到的类,接口,还有对象的构造,依赖绑定,关联过程都是非常繁琐的。如果只是按着代码把代码说一遍,其实读者是很难理解的。

我也在思考,如果有问你BeanFactory的核心的原理,那么你怎么回答呢?怎样回答才可以准确又让对方明白呢?

作者的切入点:
有了BeanFactory有什么不同?
答:没有不同,还是“拉拉扯扯”。这里的“拉”是指拉依赖的业务对象,而另一种方式是让BeanFactory推给你。

作者的思路:
有了BeanFactory以后会怎样? --》 BeanFactory怎样工作?(其中一种是XML方式) --》 XML运作方式 --》 容器的原理

看到这里,会开始感受到作者的风格。作者力求通过通俗,容易懂的方式去讲述Spring。

BeanFactory如何管理依赖绑定的信息?

  • 直接编码方式
  • 外部配置文件方式
  • 注解方式

依赖绑定的方式,跟之前的说的注入方式类似。这里不花费笔墨。

随后,在这章作者会说到Spring中 BeanFactory的一个重要的实现DefaultListableBeanFactory

查看DefautListableBeanFactory的类图,DefautListableBeanFactory作为BeanFactory的一个重要实现之余,还实现了BeanDefinitionRegistry接口。一方面,Spring的类命名的时候还是尽量符合语义还有能体现作用的,包括类图中的多个BeanFactory

DefautListableBeanFactory

BeanDefinitionRegistry = Bean - Definition - Registry (Bean定义注册处)。

作者在书中将BeanFactory比喻为图书馆,BeanDefinitionRegistry比喻为书架,书最终是放在书架上。
我觉得这个比喻还是有不合理的地方,Bean定义注册处的一个重要作用。应该是体现在注册二字。

BenDefinition实例负责保存对象的必要信息,这里的必要信息应该是指:足够可以构建对象实例的信息。包括class类型,是否抽象类、构造方法参数还以其他属性。

书架只是摆放书,这个比喻既没有体现注册,也没有体现到通过信息构造实例的过程。

到这里,作者给出了BeanFactory的一部分的实现原理。
DefaultListableBeanFactory会抽象为BeanDefinitionRegistry,注册需要受管的Bean。
然后需要使用的时候,DefaultListableBeanFactory会抽象为Bean的工厂,从工厂中获取需要的对象。

在讲解了配置文件方式,元数据方式后,来到了重点内容。

BeanFactory的XML之旅

这个章节是对 Xml的元素作一个系统的总结。

  • beans 和 bean
  • bean的属性
  • 继承
  • scope

说到scope,当然要说到singleton,prototype等。

singleton

标记为singleton的对象定义,在IoC容器中只存在一个实例,所有对该对象的引用将共享这个对象实例。

这里的单例是容器来只存在一个实例,与设计模式中的一个ClasLoader只有一个实例还是有区别的。

  • 对象实例数量。一个容器中只存在一个共享实例。
  • 对象存活时间。只要容器不销毁或退出,一直存活。
prototype

容器在接到该类型对象的请求的时候,会每次都重新生成一个新的对象实例给请求方。

request、session、global session

spring 2.0后新增加的,只适用于Web应用程序。

FactoryBean

其实我一直不理解,为什么写Spring相关的作者都喜欢写上这一句。

请不要混淆BeanFactory 和 FactoryBean。

我觉得要混淆还是很困难的。

本章最后,作者讲解了关于 scope的一个坑。
其实,简单来说。就是 prototype 的scope,也是需要经过容器去获取才会 new 一个新的实例给你。

容器背后的秘密

在面试中,关于Spring的最经常的一个问题。或者就是Spring容器的启动过程了。作者用三个小节来说明这个重点。

战略性观望

从标题就想到,是从整个大的流程来看的。
作者给出下图来描述大体的流程

容器功能实现的各个阶段

容器的启动阶段,加载Configuration MetaData(元信息),然后再对元信息进行解析和分析,组成相应的BeanDefinition,然后将BeanDefinition注册到相应的BeanDefinitionRegistry

XML 到 BeanDefinition的映射
实例化阶段

先检查对象是否已经初始化。如果没有,则根据注册的BeanDefinition所提供的信息实例化被请求的对象,注入依赖。装配完毕之后,返回给请求方。

插手“容器的启动”

这个章节,最大的问题就是代码太多。作者把BeanFactoryPostProcessor(连同完整的包名)在代码里面反复引述,严重影响阅读体验。

然后劈头盖脸就说 BeanFactoryPostProcessor让人感觉很突兀。

Allows for custom modification of an application context's bean definitions,
adapting the bean property values of the context's underlying bean factory.

允许客户修改上下文的 Bean Definitions,适配上下文更根本的Bean工厂的Bean的属性值。

Spring中的类的命名都是有一定规律的,BeanFactoryPostProcessor可以拆开为 BeanFactory Post Processor 也就是Bean工厂后置处理器。

从Spring的源码来看,BeanFactoryPostProcessor的调用是在著名的
AbstractApplicationContext中的refresh方法。

BeanFactoryPostProcessor

我觉得作者可以结合容器的refresh方法再说明BeanFactoryPostProcessor 可能会更好理解。

了解 Bean的一生

Bean的一生的重点,应该是在生命周期。作者也把Bean的生命周期罗列出来。然后重点说了

  • Bean的实例化
  • BeanPostProcessor
  • 初始化Bean 与初始化方法
  • 销毁Bean 与销毁方法

前四章算是一个引入,也讲到了 容器,Bean相关的概念。但如果是由我来说Spring是怎样完成容器的初始化,Bean的生命周期的管理,是否把这些知识点说出来就可以了呢?听我说的人可以理解,明白这个过程吗?

第一部分的笔记就先到这里,待续...

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容