spring源码分析.docx

上传人:b****7 文档编号:10307826 上传时间:2023-02-10 格式:DOCX 页数:172 大小:19.56MB
下载 相关 举报
spring源码分析.docx_第1页
第1页 / 共172页
spring源码分析.docx_第2页
第2页 / 共172页
spring源码分析.docx_第3页
第3页 / 共172页
spring源码分析.docx_第4页
第4页 / 共172页
spring源码分析.docx_第5页
第5页 / 共172页
点击查看更多>>
下载资源
资源描述

spring源码分析.docx

《spring源码分析.docx》由会员分享,可在线阅读,更多相关《spring源码分析.docx(172页珍藏版)》请在冰豆网上搜索。

spring源码分析.docx

spring源码分析

Spring5源码分析(第2版)

第一章

从现实生活理解Spring中

常用的设计模式

一、Spring中常用的设计模式

1、我们通常说的23种经典设计模式可以通过下表一目了然:

分类

设计模式

创建型

工厂方法模式(FactoryMethod)、抽象工厂模式(AbstractFactory)、建造者模式(Builder)、原型模式(Prototype)、单例模式(Singleton)

结构型

适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、装饰器模式(Decorator)、门面模式(Facade)、享元模式(Flyweight)、代理模式(Proxy)

行为型

解释器模式(Interpreter)、模板方法模式(TemplateMethod)、责任链模式(ChainofResponsibility)、命令模式(Command)、迭代器模式(Iterator)、调解者模式(Mediator)、备忘录模式(Memento)、观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、访问者模式(Visitor)

通常来说,设计模式都是混合使用,不会独立应用。

利用穷举法充分理解设计模式的应用场景。

在平时的应用中,不是用设计模式去生搬硬套,而是根据具体业务问题需要时借鉴。

2、设计模式在应用中遵循六大原则:

a、开闭原则(OpenClosePrinciple)

开闭原则就是说对扩展开放,对修改关闭。

在程序需要进行拓展的时候,不能去修改原有的代码,实现

一个热插拔的效果。

所以一句话概括就是:

为了使程序的扩展性好,易于维护和升级。

想要达到这样的

效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

b、里氏代换原则(LiskovSubstitutionPrinciple)

里氏代换原则(LiskovSubstitutionPrincipleLSP)

面向对象设计的基本原则之一。

里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。

LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

里氏代换原则是对“开-闭”原则的补充。

实现“开-闭”原则的关键步骤就是抽象化。

而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

c、依赖倒转原则(DependenceInversionPrinciple)

这个是开闭原则的基础,具体内容:

针对接口编程,依赖于抽象而不依赖于具体。

d、接口隔离原则(InterfaceSegregationPrinciple)

这个原则的意思是:

使用多个隔离的接口,比使用单个接口要好。

还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。

所以上文中多次出现:

降低依赖,降低耦合。

e、迪米特法则(最少知道原则)(DemeterPrinciple)

为什么叫最少知道原则,就是说:

一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

f、合成复用原则(CompositeReusePrinciple)

原则是尽量使用合成/聚合的方式,而不是使用继承。

设计模式之间的关系图

接下来我们只介绍在Spring中常用的设计模式。

1.1、简单工厂模式(Factory)

应用场景:

又叫做静态工厂方法(StaticFactoryMethod)模式,但不属于23种设计模式之一。

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。

Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。

归类

特点

穷举

创建型模式

是复杂工厂模式的思维模型

批量生产、标准化

1.2、工厂方法模式(FactoryMethod)

应用场景:

通常由应用程序直接使用new创建新的对象,为了将对象的创建和使用相分离,采用工厂模式,即应用程序将对象的创建及初始化职责交给工厂对象。

一般情况下,应用程序有自己的工厂对象来创建Bean.如果将应用程序自己的工厂对象交给Spring管理,那么Spring

管理的就不是普通的Bean,而是工厂Bean。

归类

特点

穷举

创建型模式

对于调用者来说,隐藏了复杂的逻辑处理过程,调用者只关心执行结果。

对于工厂来说要对结果负责,保证生产出符合规范的产品。

流水线生产

1.3、单例模式(Singleton)

应用场景:

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。

但没有从构造器级别去控制单例,这是因为Spring管理的是是任意的Java对象。

Spring下默认的Bean均为单例。

归类

特点

穷举

创建型模式

保证从系统启动到系统终止,全过程只会产生一个实例。

当我们在应用中遇到功能性冲突的时候,需要使用单例模式。

配置文件、日历、OC容器

常用单例模式写法:

饿汉式、懒汉式、注册式、序列化。

1.4、原型模式(Prototype)

应用场景:

原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

所谓原型模式,就是Java中的克隆技术,以某个对象为原型。

复制出新的对象。

显然新的对象具备原型对象的特点,效率高(避免了重新执行构造过程步骤)。

归类

特点

穷举

创建型模式

首先有一个原型。

数据内容相同,但对象实例不同(完全两个个体)。

孙悟空吹毫毛

1.5、代理模式(Proxy)

应用场景:

为其他对象提供一种代理以控制对这个对象的访问。

从结构上来看和Decorator模式类似,但Proxy是控制,更像是一种对功能的限制,而Decorator是增加职责。

Spring的Proxy模式在AOP中有体现,比如JdkDynamicAopProxy和Cglib2AopProxy。

归类

特点

穷举

结构型模式

执行者、被代理人

对于被代理人来说,这件事情是一定要做的,但是我自己又不想做或者没有时间做。

对于代理人而言,需要获取到被代理的人个人资料,只是参与整个过程的某个或几个环节。

租房中介、售票黄牛、婚介、经纪人、快递、事务代理、非侵入式日志监听

1.6、策略模式(Strategy)

应用场景:

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

本模式使得算法可独

立于使用它的客户而变化。

Spring中在实例化对象的时候用到Strategy模式,在SimpleInstantiationStrategy有使用。

归类

特点

穷举

行为型模式

最终执行结果是固定的。

执行过程和执行逻辑不一样。

旅游出行方式

1.7、模板方法模式(TemplateMethod)

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

TemplateMethod模式一般是需要继承的。

这里想要探讨另一种对TemplateMethod的理解。

Spring中的JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到JdbcTemplate

已有的稳定的、公用的数据库连接,那么我们怎么办呢?

我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。

但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。

怎么办?

那我们就用回调对象吧。

在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。

然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。

这就是TemplateMethod不需要继承的另一种实现方式。

归类

特点

穷举

行为型模式

执行流程固定,但中间有些步骤有细微差别(运行时才确定)。

可实现批量生产。

SpringORM数据模型

1.8、委派模式(Delegate)

应用场景:

不属于23种设计模式之一,是面向对象设计模式中常用的一种模式。

这种模式的原理为类B和类A是两个互相没有任何关系的类,B具有和A一模一样的方法和属性;并且调用B中的方法,属性就是调用A中同名的方法和属性。

B好像就是一个受A授权委托的中介。

第三方的代码不需要知道A的存在,也不需要和A发生直接的联系,通过B就可以直接使用A的功能,这样既能够使用到A的各种功能,又能够很好的将A保护起来了,一举两得。

归类

特点

穷举

行为型模式

要和代理模式区分开来。

持有被委托人的引用。

不关心过程,只关心结果。

经理派发工作任务、Dispatcher

1.9、适配器模式(Adapter)

SpringAOP模块对BeforeAdvice、AfterAdvice、ThrowsAdvice三种通知类型的支持实际上是借助适配器模式来实现的,这样的好处是使得框架允许用户向框架中加入自己想要支持的任何一种通知类型,上述三种通知类型是SpringAOP模块定义的,它们是AOP联盟定义的Advice的子类型。

归类

特点

穷举

结构型模式

注重兼容、转换。

适配者与被适配这之间没有层级关系,也没有必然联系。

满足has-a的关系。

编码解码、一拖三充电头、HDMI转VGA、Type-C转USB

1.10、装饰器模式(Decorator)

应用场景:

在我们的项目中遇到这样一个问题:

我们的项目需要连接多个数据库,而且不同的客户在每

次访问中根据需要会去访问不同的数据库。

我们以往在Spring和Hibernate框架中总是配置一个数据源,因而SessionFactory的DataSource属性总是指向这个数据源并且恒定不变,所有DAO在使用SessionFactory的时候都是通过这个数据源访问数据库。

但是现在,由于项目的需要,我们的DAO在访问SessionFactory的时候都不得不在多个数据源中不断切换,问题就出现了:

如何让SessionFactory在执行数据持久化的时候,根据客户的需求能够动态切换不同的数据源?

我们能不能在Spring的框架下通过少量修改得到解决?

是否有什么设计模式可以利用呢?

首先想到在Spring的ApplicationContext中配置所有的DataSource。

这些DataSource可能是各种不同类型的,比如不同的数据库:

Oracle、SQLServer、MySQL等,也可能是不同的数据源:

比如Apache提供的mons.dbcp.BasicDataSource、Spring提供的org.springframework.jndi.JndiObjectFactoryBean等。

然后SessionFactory根据客户的每次请求,将DataSource属性设置成不同的数据源,以到达切换数据源的目的。

Spring中用到的包装器模式在类名上有两种表现:

一种是类名中含有Wrapper,另一种是类名中含有Decorator。

基本上都是动态地给一个对象添加一些额外的职责。

归类

特点

穷举

结构型模式

1、注重覆盖、扩展。

2、装饰器和被装饰器都实现同一个接口,主要目的是为了扩展之后依旧保留OOP关系(同宗同源)。

3、满足is-a的关系。

IO流包装、数据源包装、简历包装

1.11、观察者模式(Observer)

应用场景:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象

都得到通知并被自动更新。

Spring中Observer模式常用的地方是Listener的实现。

如ApplicationListener。

归类

特点

穷举

行为型模式

一般由两个角色组成:

发布者和订阅者(观察者)。

观察者通常有一个回调,也可以没有。

监听器、日志收集、短信通知、邮件通知

1.12、各设计模式对比及编程思想总结

设计模式

一句话归纳

工厂模式(Factory)

只对结果负责,不要三无产品。

单例模式(Singleton)

保证独一无二。

适配器模式(Adapter)

需要一个转换头(兼容)。

装饰器模式(Decorator)

需要包装,但不改变本质(同宗同源)。

代理模式(Proxy)

办事要求人,所以找代理。

观察者模式(Observer)

完成时通知我。

策略模式(Strategy)

我行我素,达到目的就行。

模板模式(Template)

流程标准化,原料自己加。

委派模式(Delegate)

干活是你的(普通员工),功劳是我的(项目经理)。

原型模式(Prototype)

拔一根猴毛,吹出千万个。

编程思想总结

Spring思想

应用场景(特点)

一句话归纳

AOP

AspectOrientedProgramming(面向切面编程)

找出多个类中有一定规律的代码,开发时拆开,运行时再合并。

面向切面编程,即面向规则编程。

解耦,专人做专事。

OOP

ObjectOrientedProgramming(面向对象编程)

归纳总结生活中一切事物。

封装、继承、多态。

BOP

BeanOrientedProgramming(面向Bean编程)

面向Bean(普通的java类)设计程序。

一切从Bean开始。

IOC

InversionofControl(控制反转)

将new对象的动作交给Spring管理,并由Spring保存已创建的对象(IOC容器)。

转交控制权(即控制权反转)。

DI/DL

DependencyInjection(依赖注入)或者DependencyLookup(依赖查找)

依赖注入、依赖查找,Spring不仅保存自己创建的对象,而且保存对象与对象之间的关系。

注入即赋值,主要三种方式构造方法、set方法、直接赋值。

先理清关系再赋值。

第二章

SpringWeb应用开发篇

二、Spring源码版本命名规则及下载安装

2.1、Spring源码版本命名规则

(1)首先看看某些常见软件的版本号:

LinuxKernel:

0.0.1,1.0.0,2.6.32,3.0.18...,若用X.Y.Z表示,则偶数Y表示稳定版本,奇数Y表示开发版本。

Windows:

Windows98,Windows2000,Windowsxp,Windows7...,最大的特点是杂乱无章,毫无规律。

SSHClient:

0.9.8。

OpenStack:

2014.1.3,2015.1.1.dev8。

从上可以看出,不同的软件版本号风格各异,随着系统的规模越大,依赖的软件越多,如果这些软件没有遵循一套规范的命名风格,容易造成DependencyHell。

所以当我们发布版本时,版本号的命名需要遵循某种规则,其中SemanticVersioning2.0.0定义了一套简单的规则及条件来约束版本号的配置和增长。

本文根据SemanticVersionning2.0.0和SemanticVersioning3.0.0选择性的整理出版本号命名规则指南。

(2)版本号命名规则指南

版本号的格式为X.Y.Z(又称Major.Minor.Patch),递增的规则为:

X表示主版本号,当API的兼容性变化时,X需递增。

Y表示次版本号,当增加功能时(不影响API的兼容性),Y需递增。

Z表示修订号,当做Bug修复时(不影响API的兼容性),Z需递增。

详细的规则如下:

X,Y,Z必须为非负整数,且不得包含前导零,必须按数值递增,如1.9.0->1.10.0->1.11.0

0.Y.Z的版本号表明软件处于初始开发阶段,意味着API可能不稳定;1.0.0表明版本已有稳定的API。

当API的兼容性变化时,X必须递增,Y和Z同时设置为0;当新增功能(不影响API的兼容性)或者API被标记为Deprecated时,Y必须递增,同时Z设置为0;当进行bugfix时,Z必须递增。

先行版本号(Pre-release)意味该版本不稳定,可能存在兼容性问题,其格式为:

X.Y.Z.[a-c][正整数],如1.0.0.a1,1.0.0.b99,1.0.0.c1000。

开发版本号常用于CI-CD,格式为X.Y.Z.dev[正整数],如1.0.1.dev4。

版本号的排序规则为依次比较主版本号、次版本号和修订号的数值,如1.0.0<1.0.1<1.1.1<2.0.0;对于先行版本号和开发版本号,有:

1.0.0.a100<1.0.0,2.1.0.dev3<2.1.0;当存在字母时,以ASCII的排序来比较,如1.0.0.a1<1.0.0.b1。

注意:

版本一经发布,不得修改其内容,任何修改必须在新版本发布!

一些修饰的词

Snapshot:

版本代表不稳定、尚处于开发中的版本

Alpha:

内部版本

Beta:

测试版

Demo:

演示版

Enhance:

增强版

Free:

自由版

FullVersion:

完整版,即正式版

LTS:

长期维护版本

Release:

发行版

RC:

即将作为正式版发布

Standard:

标准版

Ultimate:

旗舰版

Upgrade:

升级版

Spring版本命名规则

2).Release版本则代表稳定的版本

3).GA版本则代表广泛可用的稳定版(GeneralAvailability)

4).M版本则代表里程碑版(M是Milestone的意思)具有一些全新的功能或是具有里程碑意义的版本。

4).RC版本即将作为正式版发布

2.2、Spring5源码下载

第一步:

第二步:

下载gradlehttp:

//downloads.gradle.org/distributions/gradle-1.6-bin.zip

第三步:

解压,配置GRADLE_HOME和Path

第四步:

验证gradle-v,环境变量是否正确

第五步:

点击gradlew.bat构建项目

三、Spring5概述

Spring是一个开源的轻量级JavaSE(Java标准版本)/JavaEE(Java企业版本)开发应用框架,其目的是用于简化企业级应用程序开发。

应用程序是由一组相互协作的对象组成。

而在传统应用程序开发中,一个完整的应用是由一组相互协作的对象组成。

所以开发一个应用除了要开发业务逻辑之外,最多的是关注如何使这些对象协作来完成所需功能,而且要低耦合、高内聚。

业务逻辑开发是不可避免的,那如果有个框架出来帮我们来创建对象及管理这些对象之间的依赖关系。

可能有人说了,比如“抽象工厂、工厂方法设计模式”不也可以帮我们创建对象,“生成器模式”帮我们处理对象间的依赖关系,不也能完成这些功能吗?

可是这些又需要我们创建另一些工厂类、生成器类,我们又要而外管理这些类,增加了我们的负担,如果能有种通过配置方式来创建对象,管理对象之间依赖关系,我们不需要通过工厂和生成器来创建及管理对象之间的依赖关系,这样我们是不是减少了许多工作,加速了开发,能节省出很多时间来干其他事。

Spring框架刚出来时主要就是来完成这个功能。

Spring框架除了帮我们管理对象及其依赖关系,还提供像通用日志记录、性能统计、安全控制、异常处理等面向切面的能力,还能帮我管理最头疼的数据库事务,本身提供了一套简单的JDBC访问实现,提供与第三方数据访问框架集成(如Hibernate、JPA),与各种JavaEE技术整合(如JavaMail、任务调度等等),提供一套自己的web层框架SpringMVC、而且还能非常简单的与第三方Web框架集成。

从这里我们可以认为Spring是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力,从而使我们可以更自由的选择到底使用什么技术进行开发。

而且不管是JAVASE(C/S架构)应用程序还是JAVAEE(B/S架构)应用程序都可以使用这个平台进行开发。

让我们来深入看一下Spring到底能帮我们做些什么?

3.1、一切从Bean开始

1996,Java还只是一个新兴的、初出茅庐的编程语言。

人们之所以关注她仅仅是因为,可以使用Java的Applet来开发Web应用。

但这些开发者很快就发现这个新兴的语言还能做更多的事情。

与之前的所有语言不同,Java让模块化构建复杂的系统成为可能(当时的软件行业虽然在业务上突飞猛进,但当时开发用的是传统的面向过程开发思想,软件的开发效率一直踟蹰不前。

伴随着业务复杂性的不断加深,开发也变得越发困难。

其实,当时也是面向对象思想飞速发展的时期,她在80年代末被提出,成熟于90年代,现今大多数编程语言都是面向对象的,当然这是后话了)。

他们为Applet而来,为组件化而留。

这便是最早的Java。

同样在这一年的12月,Sun公司发布了当时还名不见经传但后来人尽皆知的JavaBean1.00-A规范。

早期的JavaBean规范针对于Java,她定义了软件组件模型。

这个规范规定了一整套编码策略,使简单的Java对象不仅可以被重用,而且还可以轻松地构建更为复杂的应用。

尽管JavaBean最初是为重用应用组件而设计的,但当时他们却是主要用作构建窗体控件,毕竟在PC时代那才是主流。

但相比于当时正如日中天的Delphi、VB和C++,他看起来还是太简易了,以至于无法胜任任何"实际的"工作。

复杂的应用通常需要诸如事物、安全、分布式等服务的支持,但JavaBean并未直接提供。

所以到了1998年3月,Sun发布了EJB1.0规范,该规范把Java组件的设计理念延伸到了服务器端,并提供了许多必须的企业级服务,但他也不再像早期的JavaBean那么简单了。

实际上,除了名字,EJBBean已经和JavaBean没有任何关系了。

尽管现实中有很多系统是基于EJB构建的,但EJB从来没有实现它最初的设想:

简化开发。

EJB的声明式编程模型的确简化了很多基础架构层面的开发,例如事务和安全;但另一方面EJB在部署描述符和配套代码实现等方面变得异常复杂。

随着时间的推移,很多开发者对EJB已经不再抱有幻想,开始寻求更简洁的方法。

现在Java组件开发理念重新回归正轨。

新的编程技术AOP和DI的不断出现,他们为JavaBean提供了之前EJB才能拥有的强大功能。

这些技术为POJO提供了类似EJB的声明式编程模型,而没有引入任何EJB的复杂性。

当简单的JavaBean足以胜任时,人们便不愿编写笨重的EJB组件了。

客观地讲,EJB的发展甚至促进了基于POJO的编程模型。

引入新的理念,最新的EJB规范相比之前的规范有了前所未有的简化,但对很多开发者而言,这一切的一切都来得太迟了。

到了EJB3规范发布时,其他基于POJO的开发架构已经成为事实的标准了,而Spring框架也是在这样的大环境下出现的。

3.2、Spring设计的初衷

Spring是为解决企业级应用开发的复杂性而设计,她可以做很多事。

但归根到底支撑Spring的仅仅是少许的基本理念,而所有地这些的基本理念都能可以

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1