首页 > > > OSGI入门和整合Spring.pdf

OSGI入门和整合Spring.pdf

OSGI入门和整合Spring.pdf

上传者: 07122294 2014-02-15 评分1 评论0 下载1 收藏10 阅读量741 暂无简介 简介 举报

简介:本文档为《OSGI入门和整合Springpdf》,可适用于软件工程领域,主题内容包含OSGI入门和整合Spring概述本文用于OSGI基本入门并添加对Spring的整合本文假设读者对Eclipse、OSGISpring的概念和用法有符等。

OSGI入门和整合Spring概述本文用于OSGI基本入门,并添加对Spring的整合,本文假设读者对Eclipse、OSGI,Spring的概念和用法有基本了解,本文仅供参考,希望起到抛砖引玉的效果,希望对大家能有帮助,能节省一点查资料的时间就善莫大焉了。若发现纰漏和疑问,望不吝指教——E-Mail:Caichaowei@gmail.com。感谢Powerpiggy,Hypaspist的指导和帮助。蔡超伟2008年4月一、创建提供服务的OSGIBundle1.创建一个Plug-in工程2.填入工程名,如图选择3.直接下一步,然后点击Finish,会显示如下图:4.选择Dependencies,添加5.点击debug的虫子图标,选择OpenDebugDialog…出现下图界面后,保证在Workspace中选择刚创建的bundle,在点击“AddRequiredBundles”,确保如下3个被选中:org.eclipse.osgiorg.eclipse.osgi.servicesorg.eclipse.equinox.ds注意最后一个org.eclipse.equinox.ds需要手工指定,该包如果你的Eclipse下没有则需要下载安装,只有具有该jar包才能从以配置文件的方式注册服务(见后述的service.xml文件)。6.点击Debug后在控制台显示至此,一个最基本的Bundle就完成了,但此时它还不能对外提供任何服务。7.创建一个接口IDisplay,并且创建一个实现类Display,实现其显示信息的方法setDescInfor,内容就是将传入的参数在控制台打印出来,项目结构如图:文件内容如下:/***IDisplay.java*/publicclassDisplayimplementscom.infotech.bpr.autodisplay.display.IDisplay{publicvoidsetDescInfor(StringstrInfor){System.out.println(strInfor);}}/***Display.java*/packagecom.infotech.bpr.autodisplay.display;importorg.osgi.service.component.ComponentContext;publicclassDisplayimplementscom.infotech.bpr.autodisplay.display.IDisplay{publicvoidsetDescInfor(StringstrInfor){System.out.println("显示:"+strInfor);}/*activate方法会在Bundle加载完毕后自动调用,deactivate会在Bundle卸载时自动调用。*/protectedvoidactivate(ComponentContextcontext){System.out.println("显示器激活");}protectedvoiddeactivate(ComponentContextcontext){System.out.println("显示器卸载");}}/***Activator.java*/packagecom.infotech.bpr.autodisplay;importorg.osgi.framework.BundleActivator;importorg.osgi.framework.BundleContext;publicclassActivatorimplementsBundleActivator{publicvoidstart(BundleContextcontext)throwsException{System.out.println("显示组件启动");}publicvoidstop(BundleContextcontext)throwsException{System.out.println("显示组件停止");}}创建一个叫OSGI-INF的目录,下面创建一个名为service.xml的文件内容如下:<?xmlversion="1.0"encoding="UTF-8"?><componentname="DisplayService"><implementationclass="com.infotech.bpr.autodisplay.display.Display"/><service><provideinterface="com.infotech.bpr.autodisplay.display.IDisplay"/></service></component>上述内容的含义为声明一个名为DisplayService的组件,它对外提供接口Idisplay,实现类是Display。8.在MANIFEST.MF文件编辑器里,选择Runtime,在Exportedpackages里添加Idispaly接口所在的包在源码里添加如下一行:Service-Component:OSGI-INF/service.xml上述操作的意思为:此Bundle对外提供的服务包为com.infotech.bpr.autodisplay.display,其说明文件为OSGI-INF/service.xml9.最后MANIFEST.MF的内容如下:Manifest-Version:1.0Bundle-ManifestVersion:2Bundle-Name:AutodisplayPlug-inBundle-SymbolicName:com.infotech.bpr.autodisplayBundle-Version:1.0.0Bundle-Activator:com.infotech.bpr.autodisplay.ActivatorBundle-Vendor:INFOTECHImport-Package:org.osgi.framework;version="1.4.0",org.osgi.service.component;version="1.0.0"Export-Package:com.infotech.bpr.autodisplay.displayService-Component:OSGI-INF/service.xml简单说明:Import-Package:指需要依赖的包Export-Package:指对外暴露的接口包名Service-Component:指定提供服务的组件说明文件信息这样一个提供简单打印信息服务的Bundle就完成了!二、创建使用服务的OSGIBundle1.按第一部分所述1~6步创建一个新的Bundle工程2.在dependencies的ImportedPackages里面添加第一部分所创建的提供服务的bundle包3.生成准备调用服务的类AutoTallyTaskPro,其中定义一个类型第一部分中定义的接口IDispay的变量display,生成getter,setter,另外写一个unSetDisplay方法,用于释放display对象。最后文件内容如下:/***Activator.java*/packagecom.infotech.brp.autotally;importorg.osgi.framework.BundleActivator;importorg.osgi.framework.BundleContext;publicclassActivatorimplementsBundleActivator{publicvoidstart(BundleContextcontext)throwsException{System.out.println("自动记账程序启动");}publicvoidstop(BundleContextcontext)throwsException{System.out.println("自动记账程序停止");}}/***AutoTallyTaskProc.java*/packagecom.infotech.brp.autotally;importjava.util.Map;importcom.infotech.bpr.autodisplay.display.IDisplay;importorg.osgi.service.component.ComponentContext;publicclassAutoTallyTaskProcimplementsIAutoTallyTaskProc{privateIDisplaydisplay;publicIDisplaygetDisplay(){returndisplay;}publicvoidsetDisplay(IDisplaydispaly){System.out.println("自动记账setDisplay");this.display=dispaly;}publicvoidunSetDisplay(IDisplaydispaly){System.out.println("自动记账unSetDisplay");if(this.display==dispaly){display=null;}}protectedvoidactivate(ComponentContextcontext){display.setDescInfor("自动记账激活,调用显示器");}publicvoiddeactivate(ComponentContextcontext){display.setDescInfor("自动记账停止调用显示器");}}4.下面配置注入IDisplay接口对象:创建一个叫OSGI-INF的目录,下面创建一个名为components.xml的文件,内容如下:<?xmlversion="1.0"encoding="UTF-8"?><componentname="Autotally"><implementationclass="com.infotech.brp.autotally.AutoTallyTaskProc"/><referencename="Displayer"interface="com.infotech.bpr.autodisplay.display.IDisplay"bind="setDisplay"unbind="unSetDisplay"cardinality="1..1"policy="dynamic"/></component>在上面声明了这个组件的名称为Autotally,实现类为com.infotech.brp.autotally.AutoTallyTaskProc,还指定了其中绑定服务的类型和绑定、解绑方法。5.在MANIFEST.MF中添加:Service-Component:OSGI-INF/components.xml,最后MANIFEST.MF的内容如下:Manifest-Version:1.0Bundle-ManifestVersion:2Bundle-Name:AutotallyPlug-inBundle-SymbolicName:com.infotech.brp.autotallyBundle-Version:1.0.0Bundle-Activator:com.infotech.brp.autotally.ActivatorBundle-Vendor:INFOTECHImport-Package:com.infotech.bpr.autodisplay.display,org.osgi.framework;version="1.4.0",org.osgi.service.component;version="1.0.0"Service-Component:OSGI-INF/components.xml6.运行后能看到组件的调用过程:输入ss查看组件运行情况如下图:输入stop86,然后输入stop87,如下图:至此,一个完整的简单OSGI服务创建和调用实例已经全部展示完毕,在往下的过程中我们将整合Spring和OSGI框架。三、对服务使用Spring1.接下来将服务Bundle放入Spring环境中处理,首先下载SpringDynamicModulesforOSGi(tm)ServicePlatforms并安装,如图:在Opendebugdialog的bundle中添加上面的包(第一、二部分所添加的包全部保留)。2.在项目下添加SPRING-INF目录,下面添加一个名为springservice.xml的文件,如图内容如下:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:osgi="http://www.springframework.org/schema/osgi"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/osgihttp://www.springframework.org/schema/osgi/spring-osgi.xsd"><beanid="AutoDisplay"class="com.infotech.bpr.autodisplay.display.Display"></bean><osgi:serviceid="SAutoDisplay"ref="AutoDisplay"interface="com.infotech.bpr.autodisplay.display.IDisplay"></osgi:service></beans>3.将MANIFEST.MF的内容改成Manifest-Version:1.0Bundle-ManifestVersion:2Bundle-Name:AutodisplayPlug-inBundle-SymbolicName:com.infotech.bpr.autodisplayBundle-Version:1.0.0Bundle-Activator:com.infotech.bpr.autodisplay.ActivatorBundle-Vendor:INFOTECHImport-Package:org.osgi.framework;version="1.4.0",org.osgi.service.component;version="1.0.0"Export-Package:com.infotech.bpr.autodisplay.displaySpring-Context:SPRING-INF/springservice.xml注意和第一部分的MANIFEST.MF内容对比,会发现Service-Component被替换成了Spring-Context.4.这时再运行,控制台打印信息如图:黑字部分显示出Bundle已经正常运行,红字为Spring打印出的调试信息。注意:与第一、二部分的运行相比,少了输出:“显示器激活”,即Display类的Activate方法没有执行(随后说明)。输入ss查看Bundles运行状态后再停止之,如下图:对比第一、二部分的运行效果,可以发现在unSet之后,没有“显示器卸载”的输出,即其deactivate方法也没有执行(随后说明)。关于activate和deactivate不会自动执行,笔者没有找到好的解决方法。但根据Spring-DM的规范,它并不推荐如此,因为两个方法的声明用到ComponentContext,换句话讲,这将使你的代码和执行环境上下文绑定,除非逼不得已,并不支持这样做。笔者现在采用的方法是将服务调用者本身也定制为一个服务(但不需对外提供任何接口,仅仅是注册一个服务),这样即可利用其registered和unregistered事件来实现activate和deactivate一样的功能。四、对服务调用者使用Spring1同第三部分的1、2步骤,只是xml文件内容为:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:osgi="http://www.springframework.org/schema/osgi"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/osgihttp://www.springframework.org/schema/osgi/spring-osgi.xsd"><beanid="AutoTallyTaskProc"class="com.infotech.brp.autotally.AutoTallyTaskProc"></bean><osgi:referenceid="ConfigControl"interface="com.infotech.bpr.autodisplay.display.IDisplay"><osgi:listenerref="AutoTallyTaskProc"bind-method="onBind"unbind-method="onUnbind"></osgi:listener></osgi:reference><osgi:serviceid="SAutoTally"ref="AutoTallyTaskProc"interface="com.infotech.brp.autotally.IAutoTallyTaskProc"><registration-listenerref="AutoTallyTaskProc"registration-method="serviceRegistered"unregistration-method="serviceUnregistered"/></osgi:service></beans>简单说明如下:bean元素声明了一个id为AutoTallyTaskProc的beanosgi:reference元素声明了导入提供Idisplay接口的服务,使用AutoTallyTaskProc作为其监听器,在绑定和解绑服务时分别调用onBind和onUnbind方法。osgi:service元素声明了服务SautoTally,提供接口为IautoTallyTaskProc(空接口),实现Bean为AutoTallyTaskProc。注册注销监听器也是AutoTallyTaskProc,注册完毕执行:serviceRegistered,注销完毕执行:serviceUnregistered。2改造AutoTallyTaskProc的代码如下:packagecom.infotech.brp.autotally;importjava.util.Map;importcom.infotech.bpr.autodisplay.display.IDisplay;publicclassAutoTallyTaskProcimplementsIAutoTallyTaskProc{privateIDisplaydisplay;publicIDisplaygetDisplay(){returndisplay;}publicvoidsetDisplay(IDisplaydispaly){System.out.println("自动记账setDisplay");this.display=dispaly;}publicvoidserviceRegistered(IAutoTallyTaskProcserviceInstance,MapserviceProperties){System.out.println("自动记账服务注册完毕");display.setDescInfor("Hello");}publicvoidserviceUnregistered(IAutoTallyTaskProcserviceInstance,MapserviceProperties){System.out.println("自动记账服务注销完毕");}publicvoidonBind(IDisplaydisplay,MapargMap)throwsException{System.out.println("绑定"+display.getClass().getName());this.display=(IDisplay)display;}publicvoidonUnBind(IDisplaydisplay,MapargMap)throwsException{System.out.println("解绑"+display.getClass().getName());if(this.display==display){display=null;}}}另外再写一个空的接口IautoTallyTaskProc,代码略。注意:上面所述的定义方式和代码结构是笔者所推荐的,从代码可以看出,没有任何Spring和OSGi的API引用。3最后的代码结构如下:4执行时应按顺序打印启动、绑定服务,调用服务的信息。OK!五、其他获取服务有多种方式,若使用如下XML文件配置方式需要org.eclipse.equinox.ds_1.0.0.v20070226.jar的支持。在OSGI-INF/server.xml中说明:<?xmlversion="1.0"encoding="UTF-8"?><componentname="osgitest2.invokers"><implementationclass="osgitest2.invokers"/><referencename="autotallytest"interface="osgitest.autotally.ILog"bind="setLogger"unbind="unSetLogger"cardinality="1..1"policy="dynamic"/></component>获取服务的第二种方法,在start里:/*importorg.osgi.framework.ServiceReference;simpleLogServiceTracker=newServiceTracker(context,接口类.class.getName(),null);simpleLogServiceTracker.open();simpleLogService=(接口类)simpleLogServiceTracker.getService();if(simpleLogService!=null)simpleLogService.setLogInfo("OSGI框架已经成功启动了,一切运行正常");elseSystem.out.println("没有获得服务");*/获取服务第三种方法://ServiceReferenceserviceRef=context.getServiceReference(接口类.class.getName());//Loggerlogger=(接口类)context.getService(serviceRef);//logger.setLogInfo("OSGI框架已经成功启动了,一切运行正常");若使用后两种方法,需要在Stop方法里卸载://ServiceReferenceserviceRef=context.getServiceReference(接口类.class.getName());/*if(simpleLogService!=null)simpleLogService.setLogInfo("正在结束使用");simpleLogServiceTracker.close();simpleLogServiceTracker=null;simpleLogService=null;*/OSGI入门和整合Spring概述一、创建提供服务的OSGIBundle二、创建使用服务的OSGIBundle三、对服务使用Spring四、对服务调用者使用Spring五、其他

该用户的其他资料

  • 名称/格式
  • 评分
  • 下载次数
  • 资料大小
  • 上传时间

用户评论

0/200
    暂无评论
上传我的资料

相关资料

资料评价:

/ 21
所需积分:2 立即下载
返回
顶部
举报
资料
关闭

温馨提示

感谢您对爱问共享资料的支持,精彩活动将尽快为您呈现,敬请期待!