OSGI下的web应用开发(2)

前面已经讲了开发环境的准备,接下来来讲讲本次web应用的设计。

由于是演示用途,所以业务很简单,提供一个联系人的添加页面,添加的内容包含联系人的姓名和手机号,每点击一次添加就保存到服务端并从服务端重新读取联系人列表返回。

在设计OSGI的web应用时,如何划分模块成为了一个重要的课题。下面是几种可能的形式:

  • 整个web应用为一个bundle

显然,这跟在非OSGI的环境是一样的,就是把整个应用直接作为模块使用,对于开发而言没有什么区别(只是要注意对文件系统路径的处理);热部署时整个应用将被重载

  • 分成2个部分,web层和非web层

web层是一个独立的模块,其余的内容(即service和dao)划分为一个独立的模块

这种做法是一种粗糙的模块划分,优点是对spring和hibernate等框架bundle的集成将变得轻松,因为在一个大的bundle里,不用担心classloader引起的类加载的问题

缺点也很明显,模块化的程度太低了,并且热部署时还是会引起整个应用被重载

  • 传统的3层结构,分别是web层、service层和dao层(看情况有时在web层和service层之间可以多一层facade层)

web层是一个独立的模块;service层和dao层则有两种模块划分的形式

(1)接口定义和实现放在一个模块

不推荐此类模块定义,这样使得修改模块的实现后进行部署时,由于上层的模块依赖于该层,导致发生了依赖解析,从而导致连串的重载。例如,web层是依赖于service层的,而service层是依赖于dao层的,假如service的实现发生了变化那么service必须重新update和refresh,这时web bundle会因此受牵连。

(2)接口定义和实现划分为2个模块

为了解决依赖解析引起的连串效应,这里将接口和实现分开,这样依赖关系就发生了一些微妙的变化了。

web bundle依赖于service接口bundle,service实现bundle依赖于service接口bundle,service接口bundle依赖于dao接口bundle,dao实现bundle依赖于dao接口bundle。这时只要接口的定义没有发生改变,对实现的修改将是独立的,不会对其它的bundle造成任何的影响,因为它是依赖链条的最后一环。

  • 根据业务进行模块划分
将根据不同的业务对模块进行划分,比如上面讲到的联系人业务,它会有一个ContactService和ContactDao的定义,那么这就是与它的业务息息相关的内容,可以将它们划为一个模块。
这里也涉及到3种不同的形式:
(1)service的接口和实现以及dao的接口和实现都在一个模块下
这种划分实际上就是上面讲的将非web层作为一个bundle,但是这里是以业务作为粒度进行划分,所以每个业务都有一个自己的bundle。
这种形式的优点是spring进行AOP、事务、ORM的调用都很简单,因为都在一个bundle里
缺点则是由于细分了业务模块,每个业务模块都需要进行重复的配置(即AOP、事务等的配置)

(2)service的接口和实现为一个bundle,dao的接口和实现为一个bundle
优点是使得service和dao间的互访实现模块化控制,service的修改不会影响到底层
缺点对dao实现进行修改还是会影响到service

(3)serivce的接口为一个bundle,service实现为一个bundle,dao接口为一个bundle,dao实现为一个bundle
对各个层的实现进行修改都不会影响到依赖。这是最好的方式;
但是缺点也显而易见,因为bundle将变得非常的多,维护是一个大问题。

Note:(2)和(3)同样会使得配置变得重复,因为各个模块对spring的配置都是独立的

我最终的选择:
通过对上面的各种可行的情况的分析,我选择了传统的分层结构的方式中的(2),这样即能够保证对service和dao实现的修改不会影响到各层间的依赖,也降低了对spring的重复配置
如图所示:


系统的结构设计到此结束



猜你喜欢

转载自georgezeng.iteye.com/blog/1129660