基于OSGiWeb应用开发系列
一 前言
概述:   
    接触OSGi已经有两三年了,而真正运用OSGi于项目之中,也将近两年。这两年来,因为OSGi的不太成熟也让我饱受历练。
    如果你对OSGi这个名词有点陌生,那本系列教程就不太适合你了,如果你想学习本系列教程,请你先去了解OSGi的相关概念。
    拽写本系列教程的目的在于给想要在企业应用中使用OSGi技术的同学朋友们以实际经验指导,希望能给你带来收获。
名词解释:
    OSGiOSGiOpen Service Gateway Initiative的简称,可以称是一种技术,也可以称是一个平台,亦可称之为一种规范。
    BundleOSGi中最重要的元素之一,也是OSGi中最小的物理元素。它是一个jar包,但它持有一份能够进行自我描述的元数据文件(MANIFEST.MF),虽然普通的jar包中也存在有MAN
IFEST.MF文件,但非BundlejarMANIFEST.MF文件中缺少进行自我描述的元数据信息。
    EquinoxOSGi的一个参考实现,也是Eclipse3.2+的核心。
    SSH脚手架:SSH脚手架是指由Struts+Spring+Hibernate组合在一起的开发框架。
    Spring-DMSpring-DMSpringDynamicModules的简称,是由SpringSource提供的,致力于整合Spring框架和OSGi平台的一个框架。
    Plug-in:这里的Plug-in指基于OSGi技术的插件工程。
    Maven:用来管理项目依赖及构建的一个脚本工具。
    EBR:这里的EBRSpringSource提供的Enterprise Bundle Repository的简称
入门要求:
    学习本系列教程的同学需要了解SSH脚手架,熟悉Eclipse IDE开发,对Maven有一定的了解。
前期准备
    JDK1.6+
    Eclipse3.4+
    Spring2.5.6+
    Spring-DM1.1.2+
    Maven2.0.9+
    EBR访问地址:www.springsource/repository/app
需要解决的问题
    要使SSH脚手架能够正常运行于OSGi环境,那我们首先要解决的问题有三。其一是cglib的类加载器的改造,其二是解决数据库驱动包跟数据库连接池缺少依赖的问题,其三就是整理运行于OSGi环境下的SSH脚手架需要依赖的Bundle对象。
    也许有人会说,要让Java应用程序运行OSGi那有什么困难的呢?当然,解决问题的手段多种多样,但要创建一个标准的OSGi基于OSGi的应用程序,还确实不是那么的简单。
    解决了以上所说的三个问题,基于SSH开发OSGi应用就不成问题。但该如何解决以上三个问题呢,以及解决了以上三个问题后如何来规范这种基于OSGi环境下的SSH开发呢,又该如何保证开发效率能够保持在或更优于以往开发非OSGi应用时等一系列问题呢。要想了解如何解决,敬请关注本系列文章。

二 工具介绍
这一篇,我将向大家介绍几个常用的工具,因为本人在OSGi的项目开发中,得益于这几个工具,因此有必要向大家逐一介绍。这几个工具分别是:MavenPax-constructPax-runner。当然我们开发必定少不了IDE工具,我所使用的IDE工具是Eclipse,对于IDE的使用我就不多说了。
    开发基于OSGiWeb应用,我有两种比较开发方式,一种是借助Maven跟相关的一些Maven插件,比如上面说到的Pax-constructPax-runner、还有Mavenbnd插件。另一种开发方式则是以Plug-in的方式开发。两种方式各有其优劣。在本系列文章中,我会分别介绍这两种开发方式。

Maven简介:   
    Maven是一个很不错的项目管理工具,其插件之多,也就说明了其功能之广。但本文不会详细的来介绍Maven的各种插件,这里只会简略的说一下Maven在开发基于OSGiWeb应用中所带来的便利之处及存在的弊端。
    Maven的好处:
    1、方便管理项目的组织结构
    2、方便管理项目对第三方包的依赖关系
    3、方便项目的构建
    4、方便项目在持续集成中的应用
    Maven的弊端:
    1、在项目中,经常会出现IDE被阻塞的情况,尤其在java spring框架搭建Maven子工程比较多的情况下。
    2、当项目是快照版时,如果没有设置好快照版更新策略的话,将会浪费掉你很多宝贵的开发时间。
    Maven的使用很简单,但要用好也还是需要花不少时间来了解其各种相关的插件的功能。这里简单的讲一下maven的使用,如果你用过,可以跳过这部分内容。
    Maven的安装很简单,从Apache)下载安装包,解压到自己指定的目录下,配置一个M2_HOME的系统环境变量就可以使用了。你可以在命令行下,输入mvn关键字就可以看出Maven已经可以正常工作了,前提条件是存在有Java的运行时环境。
    第一次运行mvn后,Maven会在当前用户的根目录生成一个.m2的文件夹,里面有一个repository的文件夹,这是Maven的本地仓库目录,你可以通过修改l文件来更改
repository的位置,这个l文件可以在Maven的解压目录下的conf目录中到,最好是将l文件拷贝到用户目录下的.m2文件夹中,因为运行maven的命令时,其最先会去.m2的文件夹中查有没有l文件,这是属于用户级的配置,而在%M2_HOME%/l则是属于全局性的配置,在EclpseMaven插件也需要有.m2下的l文件。关于安装EclipseMaven插件可以参考。有关Maven更详细的资料大家可以到网上搜一下,会有大把的资料供学习。

Pax-construct简介:
  Pax-construct是一个生成OSGiMaven项目的脚本工具,其安装使用也很简单。官方网址是:/display/paxconstruct/Pax+Construct,下载最新版本1.4解压到本地目录后,将其bin目录添加到环境变量PATH中,就可以使用了。其Quickstart主页地址是:/projects/pax/construct/index.html,有关详细使用,大家可以参考官方资料,你也可以按照本系列教程中的步骤来作学习使用。

Pax-runner简介:
    Pax-runner是用来运行此OSGiMaven项目的一个脚本工具,这里我们主要用到其基于Maven的插件。其官方网址是:/space/Pax+Runner。其安装跟Pax-construct一样,使用则更为简单。这里就不详细细说了。

bnd简介:
    bnd是一个将普通jar包转换成符合OSGibundle的工具,其官方网址是:www.aqute.biz/Code/Bnd,这工具在这里大家不需要太多的关注,因为使用Pax-construct构建项目时,就已经把其集成进来了,大家需要关注的是项目根目录下的osgi.bnd配置文件。这个配置文件是项目用Maven打包时给bnd的一个附加的配置文件。具体如何使用请关注后文。
   
总结:
    以上介绍的Pax的两个工具constructrunner均是使用于在本文说的第一种开发方式,这种开发方式的好处在于开发人员不需要过多的关注OSGi Bundle的东西,精力主要放在业务
代码的开发上,但需要开发人员注意一些相关的事项。而第二种开发方式则是基于EclipsePlug-in的方式,这就需要大家对OSGi的概念比较清楚,而这种开发方式在工具上的使用有了Eclipse就行,当然如果有Maven来管理项目那也是好事。但整体上讲对开发人员的要求会高一些。
三 搭建项目框架
1. 目标
这一章的目标是:通过新建一个基于Maven的OSGi的Web应用框架,来介绍OSGi的Web应用框架的搭建过程。基于这项目框架,你可以添加自己的业务模块进来,很容易就能使之应用于实际项目中。
在这个例子中,我将以用户登录模块,结合SSH框架来演示整个过程,后端数据库将采用内存数据库。当然这个例子将贯穿接下来的几个篇章。
2. 新建项目
a. 项目结构
项目结构如下:
osgiapp
|---poms
    |    |---compiled
|    |---wrappers
    |---provision
|---osgiapp-webapp
|---osgiapp-login
|      |---osgiapp-login-dto
|      |---osgiapp-login-domain
|      |---osgiapp-login-repository-impl
|      |---osgiapp-login-service
|      |---osgiapp-login-service-impl
|---othermodule
在这个项目的层次结构中,以上列出来的均是目录结构,第一层表示项目的顶级目录,poms目录下有两个子目录跟一个l文件,此l文件继承自顶级目录下的l文件,而此l文件又被compiled、wrappers子目录下的l文件所继承。compiled下的l是项目编译所依赖的pom文件,所有业务模块下的l均继承自此pom文件,而wrappers目录下的l文件是用来被改造成OSGi下的Bundle的工程继承之用。比如我们可能需要用到第三方的某个工具包,但此工具包却不是OSGi下的Bundle,且在SpringSource的EBR中也不到,那我们就需要自己动手来将其改造成OSGi下的Bundle,这个待会在相关的章节中以示例操作给大家看。