您的位置:首页 > 编程语言 > Java开发

基于Eclipse开发OSGI的简单实例

2008-11-14 13:15 501 查看
基于Eclipse开发OSGI的简单实例

一. 概述
OSGI SERVICE PLATFORM是一个基于JAVA的,开放并且提供统一接口标准的体系框架,
在OSGI中所有模块的部署都必须以Bundle 的方式来进行部署。基于这个体系框架,服务提供商,程序开发人员,软件提供商,服务网管运营商,设备提供商能够 协调地联合起来开发,部署以及管理向用户提供的各种服务。
(a) OSGI的优势:
1. 插件可热插拔 可以实现软件的动态升级
2. 代码维护 不同Bundle间依赖仅存在于接口的层面上, 有利于代码的维护。
3. 稳定、高效的系统
基于OSGI的系统采用的是微核机制,微核机制保证了系统的稳定性,微核机制的系统只要微核是稳定运行的,那么系统就不会崩溃,也就是说基于OSGI的系统不会受到运行在其中的Bundle的影响,不会因为Bundle的崩溃而导致整个系统的崩溃。
4. 规范的、可积累的模块
大部分软件公司都形成不了规范的模块开发方式,因为没有统一的规范的基础架构体系的定义,往往每个项目、每个产品都会因为架构师的偏好、技术的发展而导致模块的开发方式完全不同,这就使得软件公司在人员技能要求、培养上很难形成统一,而OSGI为这个问题提供了解决方案,基于OSGI的系统采用规范的模块开发、部署方式构建系统。

(b)Bundle划分规则

采用OSGi技术实现应用系统时,最终展现在我们面前的将是一个个的Bundle组件,那么一个应用系统应被划分为几个bundle合适呢?这就涉及到了bundle划分的实现粒度问题。我比较倾向于按层次划分的方式,下面的实例开发都将采用该种结构划分。
根据层次进行划分:
<1>Services Bundle:在OSGi中,服务是通过Java的接口来定义的,可以把定义服务的Java接口组成一个Services Bundle,并由这个Bundle向其它Bundle提供接口。
<2>服务提供者Bundle:实现Services Bundle提供的接口,并向OSGi框架注册服务。
<3>服务使用者Bundle:引用Services Bundle提供的接口,并向OSGi框架请求相应的服务。

二. 使用SpringDM的开发实例
a) 环境搭建
i. 添加Spring环境

下载spring dynamic module,当前版本是1.0-rc2。将以下jar放到eclipse/plugins目录下。
spring-osgi-core-1.0-rc2.jar
spring-osgi-io-1.0-rc2.jar
spring-osgi-extender-1.0-rc2.jar
ii. 添加Spring-OSGI环境(SpringDM)

下载spring,当前版本2.5.1,将以下jar放到eclipse/plugins目录下。
spring-beans-2.5.1.jar
spring-aop-2.5.1.jar(依赖aopalliance.osgi-1.0-SNAPSHOT.jar)
spring-core-2.5.1.jar
spring-context-2.5.1.jar
重启eclipse,并在运行选项中钩选新添加的这些bundle。

b) 创建插件项目
i. 步骤:
1. 创建一个插件工程


2. 选择an OSGI framework,并选择standard方式,我建议使用standard方式方式,因为这样我们可以不局限于equinox,可以把它部署到其他标准的OSGI容器中了。

3.我们在这里不生成Activator,因为采用了SpringDM方式,这个工作都交给Spring来完成。

c) 以上三个步骤在建立每个Bundle时基本是相同的,我们在来逐个分析这三个Bundle的建立过程。
i. 建立Service Bundle定义类
1. 定义接口
public interface MySercice {
public String getHello();
}
2. 打开MANIFEST.MF文件的runtime节点,把这个接口export出去,供其他Bundle Import使用。

ii. 建立 ServiceImpl Bundle 实现类
1. 打开MANIFEST.MF文件的Dependencies节点,把刚才定义的那个接口import进来。

2. 定义接口实现类
public class MyServiceImpl implements MySercice {
@Override
public String getHello() {
return "My name is Benson!";
}
}
3. 定义Spring-OSGI配置文件

Spring_service.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--发布OSGI服务 -->
<bean id="myService" class="com.zhouwei.service.imp.MyServiceImp"/>
<osgi:service interface="com.zhouwei.service.MyService" ref="myService"/>
</beans>
代码中蓝色code部分是我们需要注意的地方,其中“xmlns:osgi=http://www.springframework.org/schema/osgi”这句引用,是我们的Bundle支持向OSGI环境中的发布与调用。
<!--发布OSGI服务 -->部分的意义是:
<1>首先把实现类以Spring Bean的方式注入
<2><osgi:service interface=“发布出去的服务的接口” ref=“需要发布为osgi服务的spring bean”/>
因为OSGI中Bundle之间的依赖都是在接口层面上的,所以我们interface中引用的是我们要发布的接口,而ref中才是我们真正要发布出去的服务,通常为接口的实现类。

4. 配置文件的加载
打开MANIFEST.MF文件的地MANIFEST.MF节点
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Serviceimp Plug-in
Bundle-SymbolicName: serviceimp
Bundle-Version: 1.0.0
Import-Package: com.zhouwei.service
Spring-Context: META-INF/spring_service.xml
注意最后一句是我们需要添加的,是SpringDM的标识,这样Bundle启动后就知道自己将以SpringDM的方式启动了。

iii. 建立Service调用类
1. Import提供服务的接口,具体方法见ServiceImpl Bundle中的过程。

2. 建立服务调用测试类
下面代码中的start,stop类SpringDM管理,会自动调用。
public class MyTest {
private MyService myService;
public void setMyService(MyService myService) {
this.myService = myService;
}
void start() {
System.out.println("start.......");
System.out.println(myService.getHello());
}
void stop() {
System.out.println("stop.....");
}
}
3. 编写SpringDM配置文件
a) 调用服务
<osgi:reference interface=“引用服务的接口” id=”一般使用Spring Bean的名字” />
( 理論上id可以起任何名字)
<!--調用OSGI服務-->
<osgi:reference id="myService"
interface="com.benson.service.MyService">
//=================================================
<bean name="test" class="com.benson.test.MyTest"
init-method="start" destroy-method="stop">
<property name="myService" ref="myService" />
</bean>
</beans>
b) 上面Java代码中的start和stop 方法由Spring Bean维护。
c) 发布与调用服务的区别
发布服务是先定义Spring Bean,发布服务时引用该Bean。调用服务时,先使用<osgi:reference>调用该服务,而后再定义Spring Bean在Bean的property 中引用该服务。

4. 配置文件加载
具体方法见ServiceImpl Bundle中对应部分的过程
d) 运行插件项目
i. 打开run对话框

ii. 创建新配置以启动osgi framework

iii. 钩选必需的bundle,
1. Eclipse自带
org.apache.commons.logging
javax.servlet
org.eclipse.equinox.http.jetty
org.eclipse.equinox.http.servlet
org.eclipse.osgi
org.eclipse.osgi.services
org.mortbay.jetty
2. Spring和SpringDM支持
spring-beans-2.5.1.jar
spring-aop-2.5.1.jar
spring-core-2.5.1.jar
spring-context-2.5.1.jar
aopalliance.osgi-1.0-SNAPSHOT.jar
spring-osgi-core-1.0-rc2.jar
spring-osgi-io-1.0-rc2.jar
spring-osgi-extender-1.0-rc2.jar
3. 当然还有上面创建的三个BUndle

选择完毕后,点击 Validate Bundles来验证bundles间的依赖关系是否满足,若不满足,会报缺少包的提示信息;若满足,则可点击run,来启动osgi framework。

iv. OSGi控制台
如果osgi控制台中显示osgi>,而且没有任何错误信息,并且打印出我们期望的语句,则表明osgi 框架配置已成功。

在osgi>后输入ss命令,回车,会显示所有已经安装的bundle的名称,id以及状态。
输入s命令,会显示osgi服务注册表中所有已经注册的服务

三. 在纯OSGI环境中开发实例
a) 环境搭建
基本与SpringDM方式需要的环境相同,只是不用添加SpringDM那三个依赖的插件了。
b) 创建过程
i. 创建三个Bundle,与前文中SpringDM方式基本相同。需要注意的是下图中步骤一定选择生成Activator激活器,它是用来管理这个Bundle的生命周期的,在SpringDM中我们没有生成它适应为Bundle的生命周期已经由SpringDM代为管理了。

ii. 注册OSGi服务
在我们的接口实现Bundle中的Activator类的start方法中,把实现的这个服务注册到OSGI环境中去,具体方法如下:

public void start(BundleContext context) throws Exception {
// 注冊服務
registration = context.registerService(MyService.class.getName(),
new MyServiceImpl(), null);
}
iii. 使用OSGI服务
在调用服务的bundle的Activator的start方法中,我们首先实例化一个服务跟踪类ServiceTracker,它可以跟踪OSGI Service的变化状况我么可以从这类中获取具体的服务内容。

public void start(BundleContext context) throws Exception {
//獲取tracker
tracker = new ServiceTracker(context, MyService.class.getName(), null);
tracker.open();
// TestOsgi是具体的业务实现类,在它里面调用服务。
new TestOsgi().startTest(tracker);
}
//业务实现类
public class TestOsgi {
public void startTest(ServiceTracker st) {
MyService service = (MyService) st.getService();
if (service != null) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
System.out.println(service.getHello());
} else {
System.out.println("服務獲取失敗!");
}
}
}
c) 运行
运行时配置与第一种方式也基本相同,只是不用启动与SpringDM相关的bundle了。下图为运行结果。

*====================================

由于圖片不能直接從word復制過來,所有需要完整版的朋友可以到這里下載,这里還包括文章中的所有的源碼。
*=====================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: