天天看点

《Spring技术内幕》——1.2节Spring的设计目标

1.2 spring的设计目标

如果我们要简要地描述spring的设计目标,可以这么说,spring为开发者提供的是一个一站式的轻量级应用开发框架(平台)。作为平台,spring抽象了我们在许多应用开发中遇到的共性问题;同时,作为一个轻量级的应用开发框架,spring和传统的j2ee开发相比,有其自身的特点。通过这些自身的特点, spring充分体现了它的设计理念:在java ee的应用开发中,支持pojo和使用javabean的开发方式,使应用面向接口开发,充分支持oo(面向对象)的设计方法。

比如,在java ee应用开发中,传统的ejb开发需要依赖按照j2ee规范实现的j2ee应用服务器。我们的应用在设计,特别是实现时,往往需要遵循一系列的接口标准,才能够在应用服务器的环境中得到测试和部署。这种开发方式,使应用在可测试性和部署上都会受到一些影响。spring的设计理念采用了相对ejb而言的轻量级开发思想,即使用pojo的开发方式,只需要使用简单的java对象或者javabean就能进行java ee开发,这样开发的入门、测试、应用部署都得到了简化。

另一方面,在我们的应用开发中,往往会涉及复杂的对象耦合关系,如果在java代码中处理这些耦合关系,对代码的维护性和应用扩展性会带来许多不便。而如果使用spring作为应用开发平台,通过使用spring的ioc容器,可以对这些耦合关系(对java代码而言)实现一个文本化、外部化的工作,也就是说,通过一个或几个xml文件,我们就可以方便地对应用对象的耦合关系进行浏览、修改和维护,这样,可以在很大程度上简化应用开发。同时,通过ioc容器实现的依赖反转,把依赖关系的管理从java对象中解放出来,交给了ioc容器(或者说是spring框架)来完成,从而完成了对象之间的关系解耦: 原来的对象-对象的关系,转化为对象-ioc容器-对象的关系,通过这种对象-ioc容器-对象的关系,更体现出ioc容器对应用的平台作用。

作为应用平台,spring是怎样实现它的平台功能的呢?我们知道,在java企业应用中,使用j2ee应用服务器可以开发出符合企业信息化需求的软件应用,其实,在这种应用场景下,可以将j2ee应用服务器看成是java ee应用开发的平台,只是这个平台的设计是从j2ee的技术规范出发的,所以对使用者来说,对技术的理解和要求相对较高。对于spring来说,它的定位也是在java企业应用中,与我们熟知的j2ee服务器一样,起到一个应用平台和开发框架的作用;同时希望能够集成管理企业应用需要用到的资源,以及为企业应用开发提供平台支持,但因为设计的出发点不同,所以在推广和使用上更有优势。

作为应用平台,spring与unix/windows这样传统意义的操作系统在计算机系统中的作用类似,即作为用户和机器之间的平台,同时也为用户使用底层的机器资源提供了应用开发环境。不同点只在于,操作系统关心的是对存储、计算、通信、外围设备等物理资源的管理,并在管理这些资源的基础上,为用户提供一个统一的服务接口;而对于像spring这样的java ee企业应用开发而言,其关心的是一些企业应用资源的使用,比如数据的持久化、数据集成、事务处理、消息中间件、web2.0应用、分布式计算等对高效可靠处理企业数据方法的技术抽象。具体来说,在j2ee开发中,ejb提供了一种模式,而spring提供了另一种pojo的开发模式,虽然开发模式不同(也就是使用具体资源的模式不同,但出发点却都是一样的),但其整体地位和前面提到的操作系统有不少可以类比的地方。

从理解应用开发和应用平台两者关系的角度出发,可以让我们换一种视角来体会spring的设计理念,笔者认为,在对spring的内部设计进行分析时,也可以依据对传统操作系统的认知方法(算是找一个大家都熟知的参考模型来帮助我们理解spring吧),在设计上把spring划分为核心、组件和应用3个基本的层次。希望这种划分能够帮助大家在深入了解spring设计的时候,对一些具体的模块有一个大致的定位和参考。

在这样的层次划分中,我们首先会看到,spring体系的核心,类似操作系统的kernel,即ioc容器和aop模块。对于操作系统的kernel来说,进程调度器的设计是其关键部分,通过进程调度器,一方面使用“进程”这个概念来抽象物理的计算资源,另一方面,可以通过调度算法的设计来实现对计算资源的高效使用。对spring来说,也是一样的,一方面,它通过ioc容器来管理pojo对象,以及它们相互之间的耦合关系,使企业的信息(数据)资源可以用简单的java语言来抽象和描述;另一方面,可以通过aop,以动态和非侵入式的方式来增强服务的功能。所以,我们可以把ioc容器和aop模块看做spring的kernel,是平台实现的核心部分。作为核心,它们代表了最为基础的底层抽象,同时也是spring其他模块实现的基础。虽然作为使用者的我们大多数是开发者,只是在这两个模块的基础上进行相关的配置和使用,但是如果能够了解这两个核心模块的设计和实现,就像了解linux核心的实现一样,毫无疑问,会让我们对整个平台的了解更上一层楼,对平台的认识也更为全面和系统。

另外,在spring体系中,我们还会看到,在ioc和aop这两个核心模块的支持下,spring简化了java ee所进行的开发。这种简化是指,我们能够不在ejb这么厚重的环境中使用java ee的基本服务—为应用开发提供了许多即开即用的系统组件和服务,这些服务涵盖了java ee各个基本服务,对于其他的服务,也可以根据使用情况动态扩展到spring体系中(只要依据ioc和aop所约定好的特定模式)。基本说来,spring体系中已经可以包括我们在应用开发中经常用到的许多服务了,比如事务处理、web mvc、jdbc、orm、远端调用,从对用户的价值上来说,这些服务相对来说是不可忽视的,因为就算有了一个kernel,打个比方,如果linux没有实现许多驱动,linux这个操作系统对用户来说也是没有价值的。设想一下,对于一个用户,只有一个光秃秃的linux kernel拿到手里,显卡驱动没有,键盘和鼠标的驱动没有,桌面系统没有,这样的系统能使用吗?这样的平台对一般的用户来说有价值吗?同样的道理,对spring来说,有了ioc和aop就相当于有了spring的kernel,但如果没有我们前面提到的那些即开即用的服务,spring的应用和推广还会遇到很大的障碍。不过值得庆幸的是,spring通过社区和自己的努力,提供了这些看起来不起眼,却对推广起着关键作用的部分,从而构建出一个丰富的生态系统。也许,这就暗示了interface21和spring项目之间重要的不同之处。由此可以看到,这些由spring或者其生态系统提供的,类似于驱动模块的系统组件,也是spring平台的有机组成部分,通过这部分组件提供了很多简单的即开即用的java ee服务抽象,从而使应用在通过pojo来进行具体开发时,得到java ee服务的有力支持,使应用可以更关注应用的领域问题,更关注业务逻辑。同时,由于spring使用ioc容器和aop这样的核心模块来构建这些服务抽象和应用,它们本身的松耦合设计理念,可以让应用通过使用简单的开发接口或现成的应用模板,就可以方便地使用这些java ee服务。不但如此,由于这些服务是通过ioc容器和aop核心模块来提供的,对用户而言,绑定的是ioc容器和aop模块,也就是说绑定的是ioc容器/aop模块的使用接口,而不是绑定具体的java ee服务,也为应用灵活地选取不同的服务实现提供了基础。比如,根据应用需求,用户可以选择hibernate作为orm工具,也可以使用ibatis,还可以使用其他的类似工具。这些不同工具和底层服务具体实现的选择都不影响应用的架构设计,这也体现了spring的设计理念—面向接口开发而不依赖于具体的产品实现。

作为一个开源项目,就像linux一样,spring本身也依靠开源社区的力量,形成了一个开放的生态系统,开源的特性也深深影响了spring的体系设计。在spring的发展中,其本身就吸收了不少社区的好项目,比如spring的security框架就是来源于一个社区贡献acegi。这个项目原意是为spring应用设计的一个安全框架,让spring应用更方便地处理一些安全性的问题,但随着应用的推广,慢慢也被吸收到spring项目中去,成为一个spring的子项目,虽然不是spring framework的一个部分,但也是在应用开发中经常使用到的。另外,随着技术和应用的发展,spring也在对其他的技术提供支持,比如对android移动应用开发的支持,对adobe flex前端应用的支持,对osgi应用的支持等,这些都让以spring为基础构建的spring生态圈更加繁荣。

在对spring的应用过程中,我们没有看到许多在j2ee开发中经常出现的技术规范,相反的是,在spring的实现中,我们直接看到了许多java虚拟机特性的使用,这和spring提倡的pojo的开发理念是密不可分的,了解这一点,也可以帮助我们加深对spring设计理念的认识。在spring的设计中,实现aop就采用了多种方式,比如它集成了aspectj框架,同时也有proxyfactory这种代理工厂的模式,而在代理工厂的实现中,既有直接使用jvm动态代理proxy的实现,也有使用第三方代理类库cglib的实现。在设计上,这些特点很好地展示了spring循证式开发的实用主义设计理念,这些理念和实现,同时也是我们开发java ee应用很好的参考。