本文原文地址

Spring5 源码分析

一·、Spring 中常用的设计模式

1.我们通常说的23种经典设计模式:

分类 设计模式
创建型 工厂方法(Factory Method)、抽象工厂模式(Abstract Facotry)、建造者模式(Builder)、原型模式(Prototype)、单例模式(Singleton)
结构型 适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Compostite)、装饰器模式(Decorator)、门面模式(Facade)、享元模式(Flyweight)、代理模式(Proxy)
行为型 解释器模式(Interpreter)、模板方法模式(Template Method)、责任链模式(Chain of Responsibility)、命令模式(Command)、迭代器模式(Iterator)、调解者模式(Mediator)、备忘录模式(Memento)、观察者模式(Observer)、状态模式(State)、策略模式(Strategy)、访问者模式(Vistor)

通常来说,设计模式都是混合使用,不会独立应用。利用穷举法充分理解设计模式的应用场景。在平时的应用中,不是用设计模式去生搬硬套,而是根据具体业务问题需要时借鉴。

2.设计模式在应用中遵循的六大原则

1. 开闭原则(Open Close Principle)

​ 开闭原则就是对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的一个效果,我们需要使用接口和抽象类,后边的具体设计中我们会提到这点。

2. 里氏代换原则(Liskov Substitution Principle)

​ 里氏代换原则(Liskov Substitution Principle Lsp)面向对象设计的基本原则之一。里氏代换原则中说,任何基类出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉积累,软件单位的功能不受到影响时,基类才能真正的被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类和子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

3. 依赖倒转原则(Dependence Inversion Principle)

​ 这个是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

4. 接口隔离原则(Interface Segregation Principle)

​ 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思。从这看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

5. 迪米特法则(最少知道原则)(Demeter Principle)

​ 为什么叫最少知道原则,就是说:一个实体应当尽量少的与其它实体之间发生作用,使得系统功能模块相对独立。

6. 合成复用原则(Composite Reuse Principle)

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

photo/23种设计模式.jpg

介绍Spring中常用的设计模式

1.1、简单工厂模式(Facotry)

应用场景:

​ 又叫静态工厂方法(StaticFactory Method)模式,但不属于 23 种设计模式之一。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。

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

归类 特点 穷举
创建型模式 是复杂工厂模式的思维模型 批量生产、标准化

1.2、工厂方法模式(Facotry Method)

应用场景:

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

​ 一般情况下,应用程序有自己的工厂对象来创建 Bean,如果将应用程序自己的工厂对象交给 Spring 管理,那么 Spring 管理,那么 Spring 管理就不是普通的 Bean,而是工厂 Bean。

归类 特点 穷举
创建型模式 对于调用者来说,隐藏了复杂的逻辑处理过程,调用者只关心执行结果。
对于工厂来说要对结果负责,保证生产出符合规范的产品
流水线生产

1.3、单利模式(Singleton)

应用场景

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

​ Spring 中的单例模式完成了后半句话,即提供了全局的访问点 BeanFacotry。但没有从构造器级别去控制单例,这是因为 Spring 管理的是任意的 Java 对象。Spring 下默认的 Bean 均为单利。

归类 特点 穷举
创建型模式 保证从系统启动到系统终止,全过程只会产生一个实例。
当我们在应用中遇到功能性冲突的时候,需要使用单例模式。
配置文件、日历、IOC容器

常用写法

  • 饿汉式
  • 懒汉式
  • 注册时
  • 序列化

1.4、原型模式(Prototype)

应用场景:

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

​ 所谓原型模式,就是 Java 中的克隆技术,以某个对象为原型。复制出新的对象。显然新的对象具备原型对象的特点,效率高(避免了重复执行构造过程步骤)。

归类 特点 穷举
创建型模式 首先有一个原型。
数据内容相同,但对象实例不同(完全两个个体)
孙悟空吹毫毛

1.5、代理模式(Proxy)

应用场景:

​ 为其他对象提供一种代理以控制对这个对象的访问。从结构上来看和 Decorator 类似,但 Proxy 是控制,共呢个i选哪个是一种对功能的限制,而 Decorator 是增加职责。

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

归类 特点 穷举
结构型模式 执行者、被代理人
对于被代理人来说,这件事是一定要做的,但是我自己又不想做或者没有时间做。
对于代理人而言,需要获取到被代理的人的个人资料,知识参与整个过程的某个或几个环节。
租房中介、售票黄牛、婚介、经纪人、快递、事务代理、非侵入式日志监听

1.6、策略模式(Strategy)

应用场景

​ 定义一系列的算法,把它们一个个封装起来,并且是他们可相互替换。本模式使得算法课独立于使用它的客户而变化。

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

归类 特点 穷举
行为型模式 最终执行结果是固定的。
执行过程和执行逻辑不一样。供用户去选择
旅游出行方式、支付方式、登陆(passport)、网络爬虫

1.7、模板方法模式(Template Method)

​ 定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。Template Method 使得子类可以不改变一个算法的机构即可重定义该算法的某些特定步骤。

​ Template Method 模式一般是需要继承的。这里想要探讨另一种对 Template Method 的理解。Spring 中的 JdbcTemplate ,在用这个类的时候不想去继承这个类,因为这个类的方法太多,但是我们还是享用 JdbcTemplate 已有的稳定的、公用的数据库链接,那么我们怎么办呢?我们可以吧变化的东西抽取出来作为一个参数传入 JdbcTemplate 的方法中。但是变化的东西是一段代码,而且这段代码会用到 JdbcTemplate 中的变量。怎么办?那我们就要回调放啊发吧。在这个回调对象中定义了一个操纵 JdbcTemplate 中的变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到 JdbcTemplate,从而完成了调用。这就是 Template Method 不需要继承的另一种实现方式。

归类 特点 穷举
行为型模式 执行流程故此那个,但中间有些步骤有席位差别(运行时才确定)
可实现批量生产
Spring ORM 数据模型

1.8、委派模式(Delegate)

应用场景

​ 不属于 23 种设计模式之一,是面向对象设计模式中常用的一种模式。这种模式的原理为类 B 和类 A 是两个互相没有关系的类,B 具有和 A 一摸一样的方法和属性;并且调用 B 中的方阿飞,属性就是调用 A 中的方法和属性。B 好像就是一个受 A 授权委托的中介,第三方的代码不需要知道 A 的存在,又不需要和 A 发生直接的联系,通过 B 就可以直接使用 A 的功能,这样既能够使用到 A 的各种功能,又能够很好的将 A 保护起来了,一举两得。

归类 特点 穷举
行为型模式 要和代理模式区分开来
持有被委托人的引用
不关心过程,只关心结果
经理派发工作任务、Dispatcher

1.9、适配器模式(Adapter)

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

归类 特点 穷举
行为型模式 注重兼容、转换
适配者和被适配者之间没有层级关系,也没有必然联系。
满足 has - a 的关系。
编码解码、一拖三充电头、HDMI 转 VGA 、Type - c 转 USB

1.10、装饰器模式

应用场景

​ 在我们的项目中遇到这样一个问题:我们项目需要链接多个数据库,而且不同的客户再每次访问中根据需要回去访问不同的数据库。我们以往在 Spring 和 Hibernate 框架中总是配置一个数据源,因而 SessionFactoryDataSource 属性总是指向这个数据源并且恒定不变,所有的 DAO 在使用 SessionFactory 的时候都通过这个数据源访问数据库。但是现在,由于项目的需要,我们的 DAO 在访问 SessionFacotry 的时候都不得不在多个数据源之间不断的切换,问题就出现了:如何让 SessionFactory 在执行数据持久化的时候,根据客户的需求能够动态的切换不同的数据源?我们能不能在 Spring 的框架下通过少量修改得到解决?是否有什么设计模式可以利用呢?

​ 首先想到的是 Spring 的 ApplicationContext 中配置所有的 DataSource。这些 DataSource 可能是各种不同的类型的,比如不同的数据库: Oracle、SQL Server、 Mysql等,也可能是不同的数据源:比如不同的数据库:Oracle、SQL Server、Mysql 等,也可能是不同的数据源:比如 Apache 提供的 org.apache.commons.dbcp.BasicDataSouce、Spring 提供的 org.springframework.jndi.jnidObjectFacotryBean 等。然后 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) 完成时通知我
策略模式(Startegy) 我行我素,达到目的就行。
模板模式(Template) 流程标准化,原料自己加。
委派模式(Delegate) 干活是你的(普通员工),功劳是我的(项目经理)
原型模式(Prototype) 拔一根猴毛,吹出千万个。

编程思想总结

Spring 思想 应用场景(特点) 一句话归纳
AOP Aspect Oriented Programming(面向切面编程)
找出多个类中有一定规律的代码,开发时拆开,运行时再合并。
面向切面编程,即面向规则编程。
解耦,专人做专事
OOP Object Oriented programming(面向对象编程)
归纳总结生活中一切事物
封装、继承、多态
BOP Bean Oriented Programming(面向 Bean 编程)
面向 Bean (普通的 java 类)设计程序。
一切从 Bean 开始
IOC Inversion of Control(控制反转)
将 new 对象的动作交给 Spring 管理,并由 Spring 保存已创建的对象(IOC容器)
转交控制权(即控制反转)
DI/DL Dependency Injection(依赖注入)或者 Dependency Lookup(依赖查找)
依赖注入、依赖查找,Spring 不仅保存自己创建的对象,而且保存对象与对象之间的关系。
注入即复制,主要三种方式构造方法、set 方法、直接赋值。
先清理关系再赋值。

本文原文地址

同步原文:https://mp.weixin.qq.com/s/IhmKAJl6s8bnIfZdvZaUUw

来源于: https://javaguide.net

微信公众号:不止极客

来源于: https://javaguide.net

微信公众号:不止极客

成为百万架构师的第一课:设计模式:Spring中的设计模式的更多相关文章

  1. 使用Micrisoft.net设计方案 第一章 企业解决方案中构建设计模式

    第一章企业解决方案中构建设计模式 我们知道的系统总是由简单到复杂,而不是直接去设计一个复杂系统.如果直接去设计一个复杂系统,结果最终会导致失败.在设计系统的时候,先设计一个能够正常工作的系统,然后在此 ...

  2. 阿里架构师的这一份Spring boot使用心得:网友看到都收藏了

    阿里架构师的这一份Spring boot使用心得: 这一份PDF将从Spring Boot的出现开始讲起,到基本的环境搭建,进而对Spring的IOC及AOP进行详细讲解.以此作为理论基础,接着进行数 ...

  3. Spring中的设计模式

    [Spring中的设计模式] http://www.uml.org.cn/j2ee/201301074.asp [详解设计模式在Spring中的应用]    [http://www.geek521.c ...

  4. JDK和Spring中的设计模式

    创建型 1)工厂方法 Collection.iterator() 由具体的聚集类来确定使用哪一个Iterator 2)单例模式 Runtime.getRuntime() 3)建造者模式 StringB ...

  5. 每位架构师都应该熟知的 10 个 SOA 设计模式

    这 10 个 SOA 设计模式是如此之重要,其应用是如此之广泛,以至于它们都有些显而易见了. 1. 服务无关 服务无关实现对多种业务通用的逻辑.将服务无关的逻辑分离成离散的服务以方便服务的重用和整合. ...

  6. 架构师系列文:通过Spring Cloud组件Hystrix合并请求

    在前文里,我们讲述了通过Hystrix进行容错处理的方式,这里我们将讲述通过Hystrix合并请求的方式 哪怕一个URL请求调用的功能再简单,Web应用服务都至少会开启一个线程来提供服务,换句话说,有 ...

  7. Java 架构师+高并发+性能优化+Spring boot大型分布式项目实战

    视频课程内容包含: 高级 Java 架构师包含:Spring boot.Spring cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.Zer ...

  8. 阿里架构师的工作总结:Spring Cloud在架构演进中起到的作用

    Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,本篇主要解答这两个问题:Spring Cloud在微服务的架构中都做了哪些事情?Spring Cloud提供的这些功 ...

  9. 你真的了解微服务架构吗?听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构

    微服务架构是互联网很热门的话题,是互联网技术发展的必然结果.它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值.虽然微服务架构没有公认的技术标准和规范或者草案,但业 ...

  10. 听听八年阿里架构师怎样讲述Dubbo和Spring Cloud微服务架构

    转自:https://baijiahao.baidu.com/s?id=1600174787011483381&wfr=spider&for=pc 微服务架构是互联网很热门的话题,是互 ...

随机推荐

  1. 微软nuget国内源

    https://www.cnblogs.com/Leo_wl/p/16328650.html 为解决国内访问NuGet服务器速度不稳定的问题 ,这里推荐使用NuGet微软官方中国国内镜像 地址:htt ...

  2. optical simulation of quantum logic

    量子逻辑的光学模拟(PRA, 1998)  主机中<1998Cerf.pdf> 核心: 1. 用一个光子的多条路径的叠加态来表示n qubits, 那么实验上干涉仪所包含的路径数为 2^n ...

  3. Java 面试用什么项目?全是商场秒杀 RPC,我吐了

    看了几百份简历,真的超过 90% 的小伙伴的项目是商城.RPC.秒杀.论坛.外卖.点评等等烂大街的项目,人人都知道这些项目烂大街了,但大部分同学还是得硬着头皮做,没办法,网络上能找到的.教程比较完善的 ...

  4. 微软憋大招:SQL Server + Copilot = 地表最强AI数据库!

    微软憋大招:SQL Server + Copilot = 地表最强AI数据库! 微软布局代码AI霸主地位 微软在人工智能领域的布局引人注目,尤其在代码生成领域,微软通过Copilot展现出了强大的竞争 ...

  5. AI千恋万花(java调用api实现)附完整项目及注释)重置版)

    感觉博客的第一版质量有点低下了,删了重置一下,希望能给其他人的代码带来一些灵感 前情提要:https://www.cnblogs.com/h4o3/p/18523151 由于是匆忙制作的老婆系统,主界 ...

  6. hyperf的使用

    hyperf是swoole的封装框架,用起来效率还是不错的. 使用方式看手册 https://hyperf.wiki/2.2/#/zh-cn/quick-start/install 其实是靠compo ...

  7. typeScript 基础类型 (三)

    typeScript 的基础类型包含 Boolean.Number.String.null.undefined 以及 ES6 的  Symbol 和 ES10 的 BigInt. 下面介绍每种类型的使 ...

  8. GAN和CGAN——生成式对抗网络和条件生成式对抗网络

    GAN的定义 GAN是一个评估和学习生成模型的框架.生成模型的目标是学习到输入样本的分布,用来生成样本.GAN和传统的生成模型不同,使用两个内置模型以"对抗"的方式来使学习分布不断 ...

  9. C++学习笔记-Cherno C++系列

    21-23.[Cherno C++]C++中的静态(static) static变量只在编译单元内部链接 静态变量的作用域只在单个文件内 建议:在非特殊情况下,永远使用static定义全局变量以限制作 ...

  10. Linux防火墙工具之firewall

    CentOS7 的防火墙配置跟以前版本有很大区别,CentOS7这个版本的防火墙默认使用的是firewall,与之前的版本Centos 6.x使用iptables不一样 一.iptables防火墙1. ...