前面已经讲了开发环境的准备,接下来来讲讲本次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造成任何的影响,因为它是依赖链条的最后一环。
- 根据业务进行模块划分