Spring 框架蕴含的设计思想
在 Google Guava 源码讲解中,我们讲到开发通用功能模块的一些比较普适的开发思想,比如产品意识、服务意识、代码质量意识、不要重复早轮子等。今天,我们剖析一下 Spring 框架背后的一些经典设计思想(或开发技巧)。这些设计思想并非 Spring 独有,都比较通用,能借鉴应用在很多通用功能模块的设计开发中
。这也是我们学习 Spring 源码的价值所在。
1. 约定优于配置
在使用 Spring 开发的项目中,配置往往会比较复杂、繁琐。比如,我们利用 Spring MVC 来开发 Web 应用,需要配置每个 Controller 类以及 Controller 类中的接口对应的 URL。
如何来简化配置呢?一般来讲,有两种方法,一种是基于注解,另一种是基于约定
。这两种配置方式在 Spring 中都有用到。Spring 在最小化配置方面做得淋漓尽致,有很多值得我们借鉴的地方。
基于注解的配置方式,我们在指定类上使用指定的注解,来替代集中的 XML 配置
。比如,我们使用 @RequestMapping 注解,在 Controller 类或者接口上,标注对应的 URL;使用 @Transaction 注解表明支持事务等。
基于约定的配置方式,也常叫作“约定优于配置”或者“规约优于配置”(Convention over Configuration)。通过约定的代码结构或者命名来减少配置。说直白点,就是提供配置的默认值,优先使用默认值。程序员只需要设置那些偏离约定的配置就可以了
。
比如,在 Spring JPA(基于 ORM 框架、JPA 规范的基础上,封装的一套 JPA 应用框架)中,我们约定类名默认跟表名相同,属性名默认跟表字段名相同,String 类型对应数据库中的 varchar 类型,long 类型对应数据库中的 bigint 类型等等。
基于刚刚的约定,代码中定义的 Order 类就对应数据库中的“order”表。只有在偏离这一约定的时候,例如数据库中表命名为“order_info”而非“order”,我们才需要显示地去配置类与表的映射关系(Order 类 ->order_info 表)。
实际上,约定优于配置,很好地体现了“二八法则”
。在平时的项目开发中,80% 的配置使用默认配置就可以了,只有 20% 的配置必须用户显式地去设置。所以,基于约定来配置,在没有牺牲配置灵活性的前提下,节省了我们大量编写配置的时间,省掉了很多不动脑子的纯体力劳动,提高了开发效率。除此之外,基于相同的约定来做开发,也减少了项目的学习成本和维护成本。
2. 低侵入、松耦合
框架的侵入性是衡量框架好坏的重要指标
。所谓低侵入指的是,框架代码很少耦合在业务代码中。低侵入意味着,当我们要替换一个框架的时候,对原有的业务代码改动会很少。相反,如果一个框架是高度侵入的,代码高度侵入到业务代码中,那替换成另一个框架的成本将非常高,甚至几乎不可能。这也是一些长期维护的老项目,使用的框架、技术比较老旧,又无法更新的一个很重要的原因。
实际上,低侵入是 Spring 框架遵循的一个非常重要的设计思想。
Spring 提供的 IOC 容器,在不需要 Bean 继承任何父类或者实现任何接口的情况下,仅仅通过配置,就能将它们纳入进 Spring 的管理中
。如果我们换一个 IOC 容器,也只是重新配置一下就可以了,原有的 Bean 都不需要任何修改。
除此之外,Spring 提供的 AOP 功能,也体现了低侵入的特性。在项目中,对于非业务功能,比如请求日志、数据采点、安全校验、事务等等,我们没必要将它们侵入进业务代码中。因为一旦侵入,这些代码将分散在各个业务代码中,删除、修改的成本就变得很高。而基于 AOP 这种开发模式,将非业务代码集中放到切面中,删除、修改的成本就变得很低了
。
3. 模块化、轻量级
我们知道,十几年前,EJB 是 Java 企业级应用的主流开发框架。但是,它非常臃肿、复杂,侵入性、耦合性高,开发、维护和学习成本都不低。所以,为了替代笨重的 EJB,Rod Johnson 开发了一套开源的 Interface21 框架,提供了最基本的 IOC 功能。实际上,Interface21 框架就是 Spring 框架的前身。
但是,随着不断的发展,Spring 现在也不单单只是一个只包含 IOC 功能的小框架了,它显然已经壮大成了一个“平台”或者叫“生态
”,包含了各种五花八门的功能。尽管如此,但它也并没有重蹈覆辙,变成一个像 EJB 那样的庞大难用的框架。那 Spring 是怎么做到的呢?
这就要归功于 Spring 的模块化设计思想。我们先看一张图,如下所示,它是 Spring Framework 的模块和分层介绍图。
从图中我们可以看出,Spring 在分层、模块化方面做得非常好。每个模块都只负责一个相对独立的功能
。模块之间关系,仅有上层对下层的依赖关系,而同层之间以及下层对上层,几乎没有依赖和耦合。除此之外,在依赖 Spring 的项目中,开发者可以有选择地引入某几个模块,而不会因为需要一个小的功能,就被强迫引入整个 Spring 框架。所以,尽管 Spring Framework 包含的模块很多,已经有二十几个,但每个模块都非常轻量级,都可以单独拿来使用。正因如此,到现在,Spring 框架仍然可以被称为是一个轻量级的开发框架。
4. 再封装、再抽象
Spring 不仅仅提供了各种 Java 项目开发的常用功能模块,而且还对市面上主流的中间件、系统的访问类库,做了进一步的封装和抽象,提供了更高层次、更统一的访问接口
。比如,Spring 提供了 spring-data-redis 模块,对 Redis Java 开发类库(比如 Jedis、Lettuce)做了进一步的封装,适配 Spring 的访问方式,让编程访问 Redis 更加简单。
还有我们下节课要讲的 Spring Cache,实际上也是一种再封装、再抽象。它定义了统一、抽象的 Cache 访问接口,这些接口不依赖具体的 Cache 实现(Redis、Guava Cache、Caffeine 等)。在项目中,我们基于 Spring 提供的抽象统一的接口来访问 Cache。这样,我们就能在不修改代码的情况下,实现不同 Cache 之间的切换。
除此之外,还记得我们之前在模板模式中,讲过的 JdbcTemplate 吗?实际上,它也是对 JDBC 的进一步封装和抽象,为的是进一步简化数据库编程
。不仅如此,Spring 对 JDBC 异常也做了进一步的封装。封装的数据库异常继承自 DataAccessException 运行时异常。这类异常在开发中无需强制捕获,从而减少了不必要的异常捕获和处理。除此之外,Spring 封装的数据库异常,还屏蔽了不同数据库异常的细节(比如,不同的数据库对同一报错定义了不同的错误码),让异常的处理更加简单。
总结
- 核心就是要解耦
思考
- 课堂讨论“约定优于配置”在很多开发场景中都有体现,比如 Maven、Gradle 构建工具,它们约定了一套默认的项目目录结构,除此之外,你还能想到体现这条设计思想的其他哪些开发场景吗?
- 参照 Spring 的设计思想,分析一个你熟悉框架、类库、功能组件背后的设计思想。
参考
84 | 开源实战四(上):剖析Spring框架中蕴含的经典设计思想或原则
Spring 框架蕴含的设计思想相关推荐
- Spring框架系列之AOP思想
微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.AOP概述 (1).什么是 AOP AOP 为 Aspect Oriented Progra ...
- Spring为什么这么火 之 Spring蕴含的设计思想
目录 Spring是什么? 1.什么是IoC? 2.传统程序开发 3.控制反转式程序开发 4.理解Spring IoC 5.依赖注入[DI] 总结 前言 很多人说:"Java程序员都是Spr ...
- 轻松理解Spring框架的基本思想
说起Spring框架,就不得不说J2EE的EJB.年龄稍大一些的Java程序员对J2EE的EJB还是记忆犹新的,当时使用EJB开发大型应用系统非常时髦,Java程序员无不以掌握EJB开发技术为自豪,程 ...
- Spring框架的设计理念与设计模式分析
spring设计原理 Spring框架的设计理念与设计模式分析 2016-1-27 by Damon 摘要:Spring作为现在最优秀的框架之一,被广泛的使用并有很多对其分析的文章.本文将从另外一个视 ...
- Spring框架的事务管理及应用
Spring框架简介 Spring框架是一个2003年2月才出现的开源项目,该开源项目起源自Rod Johnson在2002年末出版的<Expert One-on-One J2EE Design ...
- Spring框架入门:(非原著,转载)
1.1. 耦合性和控制反转: 对象之间的耦合性就是对象之间的依赖性.对象之间的耦合越高,维护成本越高.因此,对象的设计应使类和构件之间的耦合最小. 例: public interface I ...
- 多图详解Spring框架的设计理念与设计模式
Spring作为现在最优秀的框架之一,已被广泛的使用,51CTO也曾经针对Spring框架中的JDBC应用做过报道.本文将从另外一个视角试图剖析出Spring框架的作者设计Spring框架的骨骼架构的 ...
- 02.springMVC设计思想及springAOP
MVC设计思想 历史问题:如果将大量的代码都写到一个方法中,后期维护不易 MVC说明: 1.M Model 数据层 数据处理/数据的持久化 2.V View 视图层 前端页面相关的内容(看到的内容) ...
- 深入学习Spring框架之一Spring的简要概括
Java开发的春天 Spring框架最初的形成,来自于最初的一位Java领域的大牛-----Rod Jahnson.这位大牛所著的一本叫做<Expert One-on-One J2EE Desi ...
最新文章
- 通过仿真和综合认识JK触发器(Verilog HDL语言描述JK触发器)
- 1090 Highest Price in Supply Chain (25 分)【难度: 一般 / 知识点: 树的遍历】
- 实践 config drive - 每天5分钟玩转 OpenStack(170)
- 疫情之下“搜索+信息流”向上,百度移动生态的未来值得期待吗?
- python爬虫框架怎么安装_celery如何在python爬虫中安装?
- SQL Server与Oracle对比学习:权限管理(一)
- python (集合和深浅拷贝)
- 银行卡号每隔4位插入空格
- linux打印机驱动教程视频,Linux打印机配置wmv视频教程
- 改造家里的开关成为智能开关,保留原有开关控制,零火版,射频遥控器篇(二)
- unity下载模型到本地并加载
- vue+canvas如何实现b站萌系登录界面
- 自己做游戏(一)-PhotonServer配置
- onedrive教育版登录不上
- 给一个字符类型的数组chas和一个整数size,请把大小为size的左半区整体右移到右半区,右半区整体移动到左边。
- tinymce富文本编辑器扩展插件-设置段落间距
- Charles 常用基础功能使用方法
- php ean13,php生成EAN_13标准条形码实例_PHP教程
- Java 面试题 —— 强类型语言和弱类型语言的区别
- Java300集速学堂(5)
热门文章
- RTSP之主流安防厂家地址
- 利用vuex和localStorage实现vue菜单权限管理(笔记)
- go gorm 关联模式_Beego 结合 GORM 操作 Mysql 数据库
- python分布式计算框架_分布式计算框架Spark
- staruml 为类的属性指定数据类型_关于python的数据类型
- Android Studio的build.gradle里面的各种版本信息
- Android移动应用基础教程【服务】
- First集、Follow集
- jdbc basedao mysql_Java使用JDBC连接mysql、sqlserver、orcle数据库的baseDao类
- 查询计算机系的所有教师,用sql查询所有计算机系的教师编号和姓名