java

位置:IT落伍者 >> java >> 浏览文章

基于OSGi和Spring开发Web应用


发布日期:2019年02月21日
 
基于OSGi和Spring开发Web应用

作为一个新的事实上的工业标准OSGi 已经受到了广泛的关注 其面向服务(接口)的基本思想和动态模块部署的能力 是企业级应用长期以来一直追求的目标Spring 是一个着名的 轻量级 JEE 开发框架其特点是面向接口编程和非侵入式的依赖注入将 OSGi 和 Spring 结合能充分发挥二者各自的特长更好地满足企业级应用开发的需求Spring 开发组织在 年发布了将 OSGi 和 Spring 结合的第一个版本SpringDM本文通过一个简单实例介绍如何利用 SpringDM 开发基于 OSGi 和 Spring 架构的 Web 应用同时探讨其中用到的关键技术及其基本思想

开发一个简单的OSGi Web应用实例

一个简单的 Web 应用

我们写一个简单的 Web 应用 l 计算两个数字的和或乘积如下图所示

一个简单例子

为了体现 OSGi bundle 的动态部署能力我们写两个 service bundle其中一个计算两个数字的和(称为 add bundle)另外一个计算两个数字的积(称为 multiply bundle) 当我们点击Compute按钮的时候如果此时 add bundle 被部署则页面将返回两个数字的和否则如果此时 multiply bundle 被部署则页面将返回两个数字的积开发环境准备

下载 Eclipse

获取所有 OSGi Equinox 和 Spring 的插件 如下图所示:

打开 Eclipse 设置 target platform 为上述插件集合

基本模块设计

该应用主要包含两个层次: 服务层和 Web 层Web 层基于 SpringMVC 实现包含处理 Web访问相关的 bundle(本例中只有一个)服务层包含处理数字计算的 bundle本例中包含一个声明服务接口的 compute interface bundle 和两个实现该服务接口的 bundle add bundle 和 multiply bundle基本模块结构如下图所示

基本框架

模块程序实现

Step 实现 Service Layer

服务层的三个 OSGi bundle 实现完毕之后如下图所示

服务层

其中 comzxnpute 是声明服务接口的 bundlecomzxnputeadd和comzxnputemultiply 是实现了服务接口的两个 bundle

zxnpute

声明一个 Compute 接口其中包含一个接口方法 computeNums()如下图所示

服务层接口 bundle

zxnputeadd

bundle comzxnputeadd 的基本程序结构如下图所示

接口实现 bundle add

在该 add bundle 中添加一个Add类实现Compute接口如下图所示

接口实现代码 Add 类

注意到我们在 METAINF 下建了一个 spring 目录并且添加了一个 computeAddcontextxml 文件系统启动时Spring 将利用该xml文件创建一个 bean 实例并把该 bean 输出为一个 OSGi service如下图所示

Spring 声明文件 computeAddcontextxml

该xml文件中osgi : service是 SpringDM 输出 OSGi service 的标记其中的 interface属性标明了该 service 实现的服务接口

zxnputemultiply

按照与add bundle 同样的方法实现 multiply bundle如下图所示

接口实现代码Multiply 类

类似的添加一个 computeMultiplycontextxml 输出 OSGi service如下图所示

Spring 声明文件computeMultiplycontextxml

Step 实现 Web Layer

Web 层只包含一个 bundlecomzxnexampleweb采用 SpringMVC 和 OSGi 构建基本程序结构如下图所示

Web Layer 程序结构

ComputeControlerjava

该JAVA类实现了 orgspringframeworkwebservletmvcController是本 web应用中核心的 servlet负责接受并处理 web 请求该类调用 ComputeServiceRef 的方法实现业务逻辑该类关键的方法是 handleRequest(…) 如下图所示

核心 servlet 类

ComputeServiceRefjava

该 JAVA 类负责引用部署的 service bundle 完成最终计算其中的 computeService 由 Spring 根据 OSGi 中实际部署的 service 进行注入本例中实际部署的 service 可能是 add bundle 或者 multiply bundle

需要特别注意的是此处体现了 SpringDM 的动态特性OSGi 的动态部署能力使得 Spring 的动态服务注入成为可能

服务消费类

HTTPContextResgistryjava

该 JAVA 类负责在 OSGi 环境中配置和注册 HTTP 服务其关键方法为 bean 初始化时调用的 init( ) 方法

在 OSGi 环境中注册 HTTP 服务

该 init 方法中第六行的 getHTTPService(…) 调用 OSGi 的 ServiceTracker 来获取 OSGi环境中注册的 HTTP 服务的引用如下图所示

使用 ServiceTracker 获取 HTTP 服务

computeWebcontextxml

该 xml 文件主要用于配置 HTTPContextResgistry bean 类以及导入对 Compute 服务接口的引用标记 osgi : reference 用于声明要导入的服务接口其 interface 属性标明了该接口的定义本例中为 comzxnputeCompute 接口

Spring 声明文件导入服务接口

computeWebDispatcherxml

该 xml 文件用于配置 ComputeControler bean类

Spring 声明文件配置核心 servlet 类

运行程序

以往开发 JEE 应用通常需要将应用服务器的 runtime 集成到开发环境中才能进行程序调试非常麻烦基于 OSGi 的应用完全可以脱离应用服务器运行这使得程序开发和调试变得非常容易直接在 Eclipse 中调试运行就可以我们在 Eclipse 中将程序运行起来如下图所示

运行 OSGi 程序

从上图中看到我们同时选择部署了 add bundle 和 multiply bundle利用 OSGi console 察看如下

察看部署的 OSGi bundle

当 OSGi 环境中同时部署有多个服务接口的实现 bundle 时OSGi 会选择一个默认的 bundle提供服务本例中Spring 会默认注入 add bundle我们通过 web 访问 l 页面

访问页面

点 Compute 按钮之后结果页面如下

访问结果

可以看出是 add bundle 提供了计算服务下面我们通过命令 <stop > 来停止 add bundle的服务

停止 add bundle

add bundle 状态变为 RESOLVED

重新访问 l 页面结果得到的是两个数字的乘积可以看出是 multiply bundl

提供了计算服务如下图所示

再次访问页面

小结

作为当前颇具生命力的两个标准和框架OSGi 和 Spring 已经初步融合在一起二者的结合为开发企业级的 Web 应用同时提供了巨大的灵活性和动态部署能力本文通过一个简单的例子描述如何开发一个基于 OSGi 和 Spring 的 Web 应用并说明了开发过程中涉及到的技术关键点

上一篇:Java 技巧:步入本地方法圣殿的七个步骤

下一篇:将Java程序作成exe文件的几种方法