﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Dreava-文章分类-OSGi</title><link>http://www.blogjava.net/benniaolk/category/44430.html</link><description>梦幻瓜哇国</description><language>zh-cn</language><lastBuildDate>Sun, 28 Mar 2010 10:18:01 GMT</lastBuildDate><pubDate>Sun, 28 Mar 2010 10:18:01 GMT</pubDate><ttl>60</ttl><item><title>Spring DM的开发示例</title><link>http://www.blogjava.net/benniaolk/articles/316756.html</link><dc:creator>Dreava</dc:creator><author>Dreava</author><pubDate>Sun, 28 Mar 2010 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/benniaolk/articles/316756.html</guid><wfw:comment>http://www.blogjava.net/benniaolk/comments/316756.html</wfw:comment><comments>http://www.blogjava.net/benniaolk/articles/316756.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/benniaolk/comments/commentRss/316756.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/benniaolk/services/trackbacks/316756.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在读本文之前，您应该对基于Equinox的开发有一定的了解，如果您还不太清楚，请参考<a class="postTitle2" id="homepage1_HomePageDays_DaysList_ctl00_DayItem_DayList_ctl00_TitleUrl" href="http://www.blogjava.net/benniaolk/articles/316755.html">基于Equinox开发HelloWorld</a>一文。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;本文讲到的例子是仿照网上甚为流行的一个例子，但苦于一直未找到源码，网上贴的都是一些转帖，代码片段，估计初学者很难将其还原并调通！我最开始弄这个咚咚的时候，其过程之痛苦，难以言喻，所以想着仿照该例子的设计，给予实现，文后贴出源码，希望能帮到大家。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;该例子是一个关于计算器的实例，osgi.example.compute bundle(下文简称compute bundle)提供了统一的计算接口：Compute，另外两个bundle分别为osgi.example.compute.add(下文简称add bundle)和osgi.example.compute.multiply(下文简称multiply bundle)，在这两个bundle中，各自对compute bundle进行不同的实现，一个实现加法，一个实现乘法。另外还有一个服务消费者osgi.example.compute.consumer bundle(下文简称consumer bundle)，consumer bundle负责消费add bundle和multiply bundle提供的服务。上述4个bundle之间的关系如下图所示：<br />
<img height="345" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/8.png" width="345" border="0" /></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建4个bundle之后的工程目录如下图所示：</p>
<p align="left"><img height="70" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/9.png" width="205" border="0" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过该示例，将演示如何利用Spring DM发布和调用OSGi服务，同时还将演示OSGi的动态服务调用能力。<br />
<br />
<strong>1.&nbsp;&nbsp; bundle osgi.example.compute&nbsp;<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compute bundle只提供一个接口——Compute，因此无需依赖更多的bundle，只需最基本的osgi即可。因为不涉及注册资源之类的，所以也无需Activator入口类。<br />
Computer接口源代码如下所示：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;osgi.example.compute;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_61_114_Open_Image" onclick="this.style.display='none'; Codehighlighter1_61_114_Open_Text.style.display='none'; Codehighlighter1_61_114_Closed_Image.style.display='inline'; Codehighlighter1_61_114_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_61_114_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_61_114_Closed_Text.style.display='none'; Codehighlighter1_61_114_Open_Image.style.display='inline'; Codehighlighter1_61_114_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;Compute&nbsp;</span><span id="Codehighlighter1_61_114_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_61_114_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;computeNums(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;y);&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000">&nbsp;&nbsp;</span></div>
<br />
<strong>2.&nbsp;&nbsp;&nbsp; bundle osgi.example.compute.add<br />
</strong>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add bundle是对compute bundle的具体服务实现，在MANIFEST.MF文件需要引入osgi.example.compute包；当然也可以通过添加依赖bundle的形式，即不引入包，而直接在Required Plug-ins中添加compute bundle。如下图所示：</p>
<img height="439" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/10.png" width="623" border="0" /><br />
<p style="margin: 0cm 0cm 0pt; text-align: left"><span style="font-size: small"></p>
<div style="border-right: #666666 1px solid; border-top: #666666 1px solid; border-left: #666666 1px solid; width: 887px; border-bottom: #666666 1px solid; height: 1px">
<p style="margin: 0cm 0cm 0pt; text-align: left"><span style="font-size: small"><strong>注意：<span style="color: #ff0000"><span style="font-family: Calibri">OSGi</span></span>官方指出，当需要用到其他<span style="color: #ff0000"><span style="font-family: Calibri">bundle</span></span>的类型时，不提倡依赖<span style="color: #ff0000"><span style="font-family: Calibri">bundle</span></span>，应该尽可能采用<span style="color: #ff0000"><span style="font-family: Calibri">Import-package</span></span>的方式引入包，因为依赖<span style="color: #ff0000"><span style="font-family: Calibri">bundle</span></span>可能在加载<span style="color: #ff0000"><span style="font-family: Calibri">bundle</span></span>的时候发生问题。</strong></span></p>
</div>
<br />
add bundle的工程结构如下图所示：<br />
<img height="225" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/11.png" width="323" border="0" /><br />
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过引入osgi.example.compute包，osgi.example.compute&nbsp; bundle被加到了add bundl的classpath当中，解决了开发时期的类型识别问题。<br />
这样一来，在add bundle中就能使用compute bundle中的接口了，Computer接口的实现如下：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;osgi.example.compute.add;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;osgi.example.compute.Compute;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_119_301_Open_Image" onclick="this.style.display='none'; Codehighlighter1_119_301_Open_Text.style.display='none'; Codehighlighter1_119_301_Closed_Image.style.display='inline'; Codehighlighter1_119_301_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_119_301_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_119_301_Closed_Text.style.display='none'; Codehighlighter1_119_301_Open_Image.style.display='inline'; Codehighlighter1_119_301_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Add&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Compute&nbsp;</span><span id="Codehighlighter1_119_301_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_119_301_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_171_296_Open_Image" onclick="this.style.display='none'; Codehighlighter1_171_296_Open_Text.style.display='none'; Codehighlighter1_171_296_Closed_Image.style.display='inline'; Codehighlighter1_171_296_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_171_296_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_171_296_Closed_Text.style.display='none'; Codehighlighter1_171_296_Open_Image.style.display='inline'; Codehighlighter1_171_296_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;computeNums(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;y)&nbsp;</span><span id="Codehighlighter1_171_296_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_171_296_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;s&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;y;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">The&nbsp;Sum&nbsp;is---</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;String.valueOf(s);&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;result;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000">&nbsp;&nbsp;</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Compute的实现已经实现了，那么如何将其发布出去呢？这个是由Spring DM负责，Spring DM利用OSGi命名空间下的&lt;service&gt;元素将bean导出为OSGi服务。最简单的形式为：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;</span><span style="color: #000000">beans:bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">beanToPublish</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.xyz.imp.MessageServiceImp</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">service&nbsp;ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">beanToPublish</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.xyz.MessageService</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从示例中可以看出，beanToPublish被service元素声明导出。<br />
另外，service结点还有一些高级属性，如depends-on、context-class-loader、ranking等待，详情请看spring dm reference。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先，需要在add bundle的工程根目录下的&#8221;META-INF&#8221;的文件夹下创建一个文件夹，取名&#8221;spring&#8221;，Spring DM能够自动解析该文件夹下所有的spring配置文件。spring配置文件的具体内容如下所示：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;?</span><span style="color: #000000">xml&nbsp;version</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">1.0</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;encoding</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">UTF-8</span><span style="color: #000000">"</span><span style="color: #000000">?&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">beans&nbsp;xmlns</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/schema/beans</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.w3.org/2001/XMLSchema-instance</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xmlns:osgi</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/schema/osgi</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/schema/beans&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/beans/spring-beans.xsd&nbsp;&nbsp;&nbsp;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http:</span><span style="color: #008000">//</span><span style="color: #008000">www.springframework.org/schema/osgi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; text-decoration: underline">http://www.springframework.org/schema/osgi/spring-osgi.xsd</span><span style="color: #008000">"&gt;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">addOsgiService</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">osgi.example.compute.add.Add</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">osgi:service&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">addService</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">addOsgiService</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">osgi.example.compute.Compute</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">osgi:service</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">beans</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如此一来，其他bundle就能通过spring dm引入接口类型为osgi.example.compute.Compute的服务了，spring dm将通过一定的服务查找策略，返回匹配的服务。<br />
<br />
<strong>3.&nbsp;&nbsp;&nbsp;&nbsp;bundle osgi.example.compute.multiply<br />
</strong>
<p>该bundle和add bundle相似，在这就不赘述了。<br />
<strong>4.&nbsp;&nbsp;&nbsp; bundle osgi.example.compute.client<br />
</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 顾名思义，该bundle将作为add 、multiply两个bundle的客户bundle，演示如何导入服务。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OSGi的测试工作比较麻烦，这方面还没研究，在这里利用spring实例化bean的时期，从构造函数入手，对服务进行测试。Client类的实现很简单，如下所示：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;osgi.example.client;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;osgi.example.compute.Compute;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_98_305_Open_Image" onclick="this.style.display='none'; Codehighlighter1_98_305_Open_Text.style.display='none'; Codehighlighter1_98_305_Closed_Image.style.display='inline'; Codehighlighter1_98_305_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_98_305_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_98_305_Closed_Text.style.display='none'; Codehighlighter1_98_305_Open_Image.style.display='inline'; Codehighlighter1_98_305_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Client&nbsp;</span><span id="Codehighlighter1_98_305_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_98_305_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img id="Codehighlighter1_107_195_Open_Image" onclick="this.style.display='none'; Codehighlighter1_107_195_Open_Text.style.display='none'; Codehighlighter1_107_195_Closed_Image.style.display='inline'; Codehighlighter1_107_195_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_107_195_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_107_195_Closed_Text.style.display='none'; Codehighlighter1_107_195_Open_Image.style.display='inline'; Codehighlighter1_107_195_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_107_195_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**&nbsp;*/</span><span id="Codehighlighter1_107_195_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;为了方便测试，采用Spring的构造注入方式，直接在构造函数中调用Compute服务&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@param</span><span style="color: #008000">&nbsp;compute&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000">&nbsp;&nbsp;<br />
<img id="Codehighlighter1_233_300_Open_Image" onclick="this.style.display='none'; Codehighlighter1_233_300_Open_Text.style.display='none'; Codehighlighter1_233_300_Closed_Image.style.display='inline'; Codehighlighter1_233_300_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_233_300_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_233_300_Closed_Text.style.display='none'; Codehighlighter1_233_300_Open_Image.style.display='inline'; Codehighlighter1_233_300_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Client(Compute&nbsp;compute)</span><span id="Codehighlighter1_233_300_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_233_300_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(compute.computeNums(</span><span style="color: #000000">5</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">6</span><span style="color: #000000">));&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000">&nbsp;&nbsp;</span></div>
</span>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 另外，因为client用到了其他几个bundle的类型，所以需要导入相应的包，步骤在上面已有讲到。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spring dm靠&lt;reference&gt;元素来引入服务，最简单的形式如下所示：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;</span><span style="color: #000000">reference&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">beanToPublish</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.xyz.MessageService</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果需要用到该服务，如某个bean包含一个com.xyz.MessageService属性，则配置该bean如下所示：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">referenceBean</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">com.nci.ReferenceBean</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">property&nbsp;name</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">messageService</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">beanToPublish</span><span style="color: #000000">"</span><span style="color: #000000">/&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;</span></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reference元素还有一些高级属性，详情请见spring dm reference。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 看一下client的spring配置文件：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #000000">&lt;?</span><span style="color: #000000">xml&nbsp;version</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">1.0</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;encoding</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">UTF-8</span><span style="color: #000000">"</span><span style="color: #000000">?&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;</span><span style="color: #000000">beans&nbsp;xmlns</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/schema/beans</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.w3.org/2001/XMLSchema-instance</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;xmlns:osgi</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/schema/osgi</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">http://www.springframework.org/schema/beans&nbsp;http://www.springframework.org/schema/beans/spring-beans.xsd&nbsp;&nbsp;&nbsp;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http:</span><span style="color: #008000">//</span><span style="color: #008000">www.springframework.org/schema/osgi&nbsp;</span><span style="color: #008000; text-decoration: underline">http://www.springframework.org/schema/osgi/spring-osgi.xsd</span><span style="color: #008000">"&gt;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">bean&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">OSGiClient</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">osgi.example.client.Client</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">constructor</span><span style="color: #000000">-</span><span style="color: #000000">arg&nbsp;ref</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">ComputeService</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">constructor</span><span style="color: #000000">-</span><span style="color: #000000">arg</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">bean</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">osgi:reference&nbsp;id</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">ComputeService</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">osgi.example.compute.Compute</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;cardinality</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">1..1</span><span style="color: #000000">"</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&lt;/</span><span style="color: #000000">osgi:reference</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #000000">&lt;/</span><span style="color: #000000">beans</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;</span></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从上面的示例，我们可以发现，服务的导出的时候都是基于接口的，服务的引用也是基于接口的，不过spring dm支持基于类的导出、导入，但是还是建议尽量基于接口，应该记住面向接口编程的思想，以应对将来有可能发生的改变。<br />
<br />
<strong>5.&nbsp;&nbsp; &nbsp;运行<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;由于add和multiply都是基于Compute接口对外导出服务，那么Client到底导入的是哪个服务呢？默认情况下，会导入启动较早的bundle服务（OSGi在bundle启动时，会为其分配一个ID值，启动越早，该值越小）。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行之前，我们需要做这么一件事，在window-&gt;preferences-&gt;plug-in development-&gt;Target Platform面板中，将Target指定为Spring DM&#8230;，如下图所示：<br />
<img height="597" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/12.png" width="1007" border="0" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 之后就可以配置运行了，随便在一个bundle工程上右键，Run As-&gt;Run Configurations，新建一个OSGi Platform运行项（右键OSGi Platform即可），如下图所示：<br />
<img height="652" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/13.png" width="958" border="0" /><br />
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;需要勾选中spring bundle版（2.5.6），spring dm的几个核心包：core、extender、io再点validate bundles按钮，校验是否已全部选中其依赖的bundle。然后即可点击运行了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行之后，我们发现控制台输出结果：<br />
The Sum is---11<br />
通过ss命令，如下：<br />
5&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; osgi.example.compute.multiply_1.0.0<br />
6&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; osgi.example.compute.add_1.0.0<br />
7&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; osgi.example.compute.client_1.0.0<br />
将6停掉:stop 6<br />
然后再refresh 7，控制台输出如下结果：<br />
The Multiply is---30<br />
通过 ss 命令，如下：<br />
5&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; osgi.example.compute.multiply_1.0.0<br />
6&nbsp;RESOLVED&nbsp;&nbsp;&nbsp; osgi.example.compute.add_1.0.0<br />
7&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; osgi.example.compute.client_1.0.0<br />
现在multiply处于运行状态，而add已经被停止，所以client导入的服务实际是由multiply提供的。<br />
</p>
<p><strong>6.&nbsp;总结</strong>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过该文档，我们已经清楚了，如何使用Spring DM导出、导入服务。Spring DM的一些高级特性请查阅spring dm reference。<br />
<br />
<br />
<strong><em>附件：<a href="/Files/benniaolk/OSGi/Spring与OSGi的整合/1.rar">osgi.example.compute.rar</a></em></strong><br />
</p>
  <img src ="http://www.blogjava.net/benniaolk/aggbug/316756.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/benniaolk/" target="_blank">Dreava</a> 2010-03-28 17:36 <a href="http://www.blogjava.net/benniaolk/articles/316756.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Equinox开发HelloWorld</title><link>http://www.blogjava.net/benniaolk/articles/316755.html</link><dc:creator>Dreava</dc:creator><author>Dreava</author><pubDate>Sun, 28 Mar 2010 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/benniaolk/articles/316755.html</guid><wfw:comment>http://www.blogjava.net/benniaolk/comments/316755.html</wfw:comment><comments>http://www.blogjava.net/benniaolk/articles/316755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/benniaolk/comments/commentRss/316755.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/benniaolk/services/trackbacks/316755.html</trackback:ping><description><![CDATA[<p>1.&nbsp;开发环境的准备</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在的eclipse都已经包含了Equinox，无需单独下载。<br />
2.&nbsp;开发OSGi的HelloWorld应用程序</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在这一节，我们将开发一个OSGi bundle，演示如何利用Equinox进行OSGi bundle的开发、运行及调试，为之后的示例做准备。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先，新建一个Plug-in工程，如下图所示：<br />
<img height="598" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/1.jpg" width="506" border="0" /><br />
</p>
<p><span>下一步，注意选择目标平台，默认为Eclipse version *，将其改成Equinox，如下图所示：</span></p>
<img height="594" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/2.png" width="499" border="0" /><br />
<p><span>之后按默认下一步即可，到最后一步时，无需根据模板创建工程，去掉默认的勾，如下图：</span></p>
<img height="593" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/3.png" width="501" border="0" /><br />
<p><span>点击完成，创建的工程目录如下图所示：</span></p>
<img height="428" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/4.png" width="682" border="0" /><br />
<span style="font-family: Calibri">从图中，可以看到，eclipse为工程自动生成了一个Activator类，如下所示：</span><br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;helloworld;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.osgi.framework.BundleActivator;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.osgi.framework.BundleContext;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_169_642_Open_Image" onclick="this.style.display='none'; Codehighlighter1_169_642_Open_Text.style.display='none'; Codehighlighter1_169_642_Closed_Image.style.display='inline'; Codehighlighter1_169_642_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_169_642_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_169_642_Closed_Text.style.display='none'; Codehighlighter1_169_642_Open_Image.style.display='inline'; Codehighlighter1_169_642_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Activator&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;BundleActivator&nbsp;</span><span id="Codehighlighter1_169_642_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_169_642_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_181_304_Open_Image" onclick="this.style.display='none'; Codehighlighter1_181_304_Open_Text.style.display='none'; Codehighlighter1_181_304_Closed_Image.style.display='inline'; Codehighlighter1_181_304_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_181_304_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_181_304_Closed_Text.style.display='none'; Codehighlighter1_181_304_Open_Image.style.display='inline'; Codehighlighter1_181_304_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_181_304_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_181_304_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;(non-Javadoc)&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000">&nbsp;&nbsp;<br />
<img id="Codehighlighter1_370_426_Open_Image" onclick="this.style.display='none'; Codehighlighter1_370_426_Open_Text.style.display='none'; Codehighlighter1_370_426_Closed_Image.style.display='inline'; Codehighlighter1_370_426_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_370_426_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_370_426_Closed_Text.style.display='none'; Codehighlighter1_370_426_Open_Image.style.display='inline'; Codehighlighter1_370_426_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;start(BundleContext&nbsp;context)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;</span><span id="Codehighlighter1_370_426_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_370_426_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Hello&nbsp;World!</span><span style="color: #000000">"</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;<br />
<img id="Codehighlighter1_438_560_Open_Image" onclick="this.style.display='none'; Codehighlighter1_438_560_Open_Text.style.display='none'; Codehighlighter1_438_560_Closed_Image.style.display='inline'; Codehighlighter1_438_560_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_438_560_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_438_560_Closed_Text.style.display='none'; Codehighlighter1_438_560_Open_Image.style.display='inline'; Codehighlighter1_438_560_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_438_560_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**/</span><span id="Codehighlighter1_438_560_Open_Text"><span style="color: #008000">/*</span><span style="color: #008000">&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;(non-Javadoc)&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@see&nbsp;org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000">&nbsp;&nbsp;<br />
<img id="Codehighlighter1_625_634_Open_Image" onclick="this.style.display='none'; Codehighlighter1_625_634_Open_Text.style.display='none'; Codehighlighter1_625_634_Closed_Image.style.display='inline'; Codehighlighter1_625_634_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_625_634_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_625_634_Closed_Text.style.display='none'; Codehighlighter1_625_634_Open_Image.style.display='inline'; Codehighlighter1_625_634_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;stop(BundleContext&nbsp;context)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;Exception&nbsp;</span><span id="Codehighlighter1_625_634_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_625_634_Open_Text"><span style="color: #000000">{&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000">&nbsp;&nbsp;</span></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有过eclipse插件开发经验的人应该很快就能明白，这就是该工程——实际上就是上一篇文章中所称的bundle在Equinox平台中的启动入口，相当于我们的熟悉的main函数，如果将该bundle运行到Equinox中，首先进入该bundle的是Activator的start方法，你可以将相关的服务、资源在该方法内完成向bundleContext的注册——文章后面会具体讲到相关内容。在运行期，如果想要该bundle停止运行，Equinox平台将调用Activator的stop方法，你可以在该方法内完成资源的注销等工作。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面我们将要完成首次的Equinox运行，将向大家展现bundle到底是如何运行起来的。为helloworld选择运行方式，如下图所示：<br />
<img height="129" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/5.png" width="528" border="0" /><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 弹出如下对话框：<br />
<img height="129" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/Spring与OSGi的整合/5.png" width="528" border="0" /><br />
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在弹出的对话框中，新建一个OSGi Framework运行环境（双击OSGi Framework即可，这里为其取名Equinox），选中helloworld(1.0.0)，然后点击右边的Add Required Bundles按钮，eclipse将自动选中运行helloworld的依赖bundle，如果有必要，可以点击右下的Validate Bundles验证按钮，验证程序正常运行所需的bundle是否都被选中，最后点击运行，回到控制台：<br />
osgi&gt; Hello World!<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以看到，之前在Activator的start方法中的输出语句已经被输出到控制台，我们可以通过命令ss查看Equinox的运行情况，可以看到一共运行了两个bundle，如下：<br />
ss</p>
<p>Framework is launched.</p>
<p>id&nbsp;State&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bundle<br />
0&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.eclipse.osgi_3.4.3.R34x_v20081215-1030<br />
1&nbsp;ACTIVE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; helloworld_1.0.0<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还记得之前讲到过的bundle的几种状态吧？helloworld已经运行起来了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么Equinox具体支持哪些命令呢？下表列出了主要的一些命令，如需查看更详细的命令清单，则可以在控制台键入help。</p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; border-top: #8064a2 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #8064a2 1pt solid; width: 142pt; padding-top: 0cm; border-bottom: #8064a2 2.25pt solid; background-color: transparent" valign="top" width="189">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>类别</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; border-top: #8064a2 1pt solid; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; padding-top: 0cm; border-bottom: #8064a2 2.25pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>命令</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; border-top: #8064a2 1pt solid; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; padding-top: 0cm; border-bottom: #8064a2 2.25pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>含义</strong></p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; background: #e5dfec; padding-bottom: 0cm; border-left: #8064a2 1pt solid; width: 142pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" width="189" rowspan="6">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>控制框架</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">launch</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">启动框架</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">shutdown</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">停止框架</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">close</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">关闭、退出框架</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">exit</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">立即退出，相当于 System.exit</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">init</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">卸载所有 bundle（前提是已经 shutdown）</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">setprop</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">设置属性，在运行时进行</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; background: #e5dfec; padding-bottom: 0cm; border-left: #8064a2 1pt solid; width: 142pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" width="189" rowspan="6">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>控制</strong><strong> bundle</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">install</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">安装</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">uninstall</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">卸载</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">start</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">启动</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">stop</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">停止</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">refresh</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">刷新</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">update</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">更新</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; background: #e5dfec; padding-bottom: 0cm; border-left: #8064a2 1pt solid; width: 142pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" width="189" rowspan="7">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>展示状态</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">status</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示安装的 bundle 和注册的服务</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">ss</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示所有 bundle 的简单状态</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><span style="font-size: small"><span style="font-family: Calibri">s</span><code><span style="font-size: 12pt; color: #000000">ervices</span></code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示注册服务的详细信息</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">packages</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示导入、导出包的状态</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">bundles</code></span></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示所有已经安装的 bundles 的状态</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">headers</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示 bundles 的头信息，即 MANIFEST.MF 中的内容</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">log</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">展示 LOG 入口信息</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; background: #e5dfec; padding-bottom: 0cm; border-left: #8064a2 1pt solid; width: 142pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" width="189" rowspan="4">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>其它</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">exec</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">在另外一个进程中执行一个命令（阻塞状态）</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">fork</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">和 EXEC 不同的是不会引起阻塞</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">gc</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">促使垃圾回收</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">getprop</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">得到属性，或者某个属性</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; background: #e5dfec; padding-bottom: 0cm; border-left: #8064a2 1pt solid; width: 142pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" width="189" rowspan="4">
            <p style="margin: 0cm 0cm 0pt; text-align: center" align="center"><strong>控制启动级别</strong></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">sl</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">得到某个 bundle 或者整个框架的 start level 信息</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">setfwsl</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">设置框架的 start level</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">setbsl</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid; background-color: transparent" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">设置 bundle 的 start level</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 68.95pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="92">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left"><code><span style="font-size: 12pt; color: #000000">setibsl</span></code></p>
            </td>
            <td style="border-right: #8064a2 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #ece9d8; background: #dfd8e8; padding-bottom: 0cm; width: 215.15pt; border-top-color: #ece9d8; padding-top: 0cm; border-bottom: #8064a2 1pt solid" valign="top" width="287">
            <p style="margin: 0cm 0cm 0pt; text-align: left" align="left">设置初始化 bundle 的 start level</p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 至此，我们已经成功的演示了helloworld，初步了解了OSGi的bundle是如何开发并运行的。<br />
<br />
</p>
<img src ="http://www.blogjava.net/benniaolk/aggbug/316755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/benniaolk/" target="_blank">Dreava</a> 2010-03-28 16:58 <a href="http://www.blogjava.net/benniaolk/articles/316755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSGi和构件化开发</title><link>http://www.blogjava.net/benniaolk/articles/316738.html</link><dc:creator>Dreava</dc:creator><author>Dreava</author><pubDate>Sun, 28 Mar 2010 03:49:00 GMT</pubDate><guid>http://www.blogjava.net/benniaolk/articles/316738.html</guid><wfw:comment>http://www.blogjava.net/benniaolk/comments/316738.html</wfw:comment><comments>http://www.blogjava.net/benniaolk/articles/316738.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/benniaolk/comments/commentRss/316738.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/benniaolk/services/trackbacks/316738.html</trackback:ping><description><![CDATA[<p>&nbsp; </p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">目前，关注</span>OSGi<span style="font-family: 宋体">的人变得越来越多，</span>OSGi<span style="font-family: 宋体">本身也早已从那个专注于嵌入式平台的&#8220;小&#8221;角色转变过来了，慢慢向企业级应用市场渗透。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">从某种角度说，</span>Eclipse<span style="font-family: 宋体">可以说是</span>OSGi<span style="font-family: 宋体">在企业应用领域的试金石，</span>2003<span style="font-family: 宋体">年</span>Eclipse3.0<span style="font-family: 宋体">做了一次架构上的调整，继续延用插件的架构思想，但是从</span>3.0<span style="font-family: 宋体">版之后，是基于</span>OSGi<span style="font-family: 宋体">的实现。也就是这一次的调整，推动了</span>Eclipse<span style="font-family: 宋体">的迅猛发展。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">这是在桌面应用的成功示例，而</span>OSGi<span style="font-family: 宋体">的目标远不止于此，以其优秀的类加载机制，可以说，只需对其进行扩展，那么就可以目标瞄准任何一个领域。谈到企业应用，无可避免的要涉及</span>Web<span style="font-family: 宋体">应用，相信大多数人都在从事该领域的开发。</span>OSGi R4<span style="font-family: 宋体">版已明确提出了对</span>Web<span style="font-family: 宋体">的支持方式——当然，这种方式还是很有限的，这一点将在后面的文章中详细说明。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">鉴于此，很多开源框架都已经或正准备发布支持</span>OSGi<span style="font-family: 宋体">的版本，比如</span>Spring DM<span style="font-family: 宋体">、</span>Struts1.8.1<span style="font-family: 宋体">、</span>CXF<span style="font-family: 宋体">等等，基本上日常所用的开源框架都发布了基于</span>OSGi<span style="font-family: 宋体">版本。另外，有不少应用服务器也已经基于</span>OSGi<span style="font-family: 宋体">进行实现，比如</span>WAS<span style="font-family: 宋体">从</span>6.1<span style="font-family: 宋体">版就已经是基于</span>OSGi<span style="font-family: 宋体">的实现，而</span>Spring<span style="font-family: 宋体">也在</span>2009<span style="font-family: 宋体">年推出了</span>Spring DM Server<span style="font-family: 宋体">，可见</span>OSGi<span style="font-family: 宋体">的吸引力还是很大的。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">那么这一切将会为以后的开发带来什么影响呢？本文试图从</span>OSGi<span style="font-family: 宋体">和构件化开发的角度认识一下该问题。</span></p>
<p style="text-indent: 24pt">OSGi<span style="font-family: 宋体">的类加载机制非常优秀，为每个运行于其中的</span>bundle<span style="font-family: 宋体">创建了独立的类加载器环境，而运行于同一个</span>OSGi<span style="font-family: 宋体">框架内部的</span>bundle<span style="font-family: 宋体">之间不像</span>Web<span style="font-family: 宋体">服务器中的</span>Web<span style="font-family: 宋体">应用那样绝缘，它们之间是可以进行包依赖的，当然</span>OSGi<span style="font-family: 宋体">也提供了服务注册等相关机制，确保</span>bundle<span style="font-family: 宋体">之间的相互协作能力。而且</span>OSGi<span style="font-family: 宋体">支持</span>bundle<span style="font-family: 宋体">动态部署。所以，系统无需停机重启，就可以实现其内部的动态更新。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">构件化开发的概念已经提了很多年了，似乎一直缺乏一种有效的机制对其进行支持。构件化开发为系统开发带来了很多好处，整个系统的开发可以按照模块的方式进行划分，从而按模块进行开发；系统由各模块之间拼装而成，通过代码一级的依赖或者服务依赖的方式；对于某个模块进行更新，只要保持接口不变，则可以实现对外界无影响。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">由于缺乏有效的底层支持，构件化开发方式一直没有推行起来。由其对于</span>Web<span style="font-family: 宋体">应用而言，想要实现构件化开发，似乎更是无从谈起。</span></p>
<p style="text-indent: 24pt">OSGi<span style="font-family: 宋体">的出现，让这一事情有所转机。传统的</span>Web<span style="font-family: 宋体">应用开发过程中，可能大多数人的做法就是将一个大的</span>Web<span style="font-family: 宋体">应用按功能模块进行划分，通过包切分来实现模块化开发，但是各模块之间并没有从物理上隔离，只是以一种组织方式上的约束，使其从表面看上去是分离的。对于这种方式，动态更新某个模块也就无从谈起了。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">而如果将</span>OSGi<span style="font-family: 宋体">引入</span>Web<span style="font-family: 宋体">应用，每个模块都对应于一个</span>bundle<span style="font-family: 宋体">，那么模块与模块之间则从物理上进行了隔离，能有效的将模块内部实现对外隐藏。模块之间的交互，可以通过接口的导出与引用来实现，对于未经导出的部分，对于其他模块是不可见的。另外，由于</span>OSGi<span style="font-family: 宋体">支持</span>bundle<span style="font-family: 宋体">的热部署，那就意味着，在当前</span>Web<span style="font-family: 宋体">应用未停机的情况下，可以对某个或某些模块（对应</span>OSGi<span style="font-family: 宋体">中的</span>bundle<span style="font-family: 宋体">）进行动态更新，而不影响整个应用的正常运行。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">这种从物理上的有效隔离的方式，为重用带来了新的方式。以前代码一级的重用，一般都通过</span>Jar<span style="font-family: 宋体">包的形式进行，而这种方式存在上述的一些缺点，即封装性不够。而通过基于</span>OSGi<span style="font-family: 宋体">的</span>bundle<span style="font-family: 宋体">的形式，则可以有效隐藏内部实现，从包一级进行隐藏（这一点个人觉得可以作为</span>Java<span style="font-family: 宋体">封装性的一种扩展，以前的封装只能做到类一级，不知道未来是否会被</span>Java<span style="font-family: 宋体">规范吸收）。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">就这一点而言，</span>OSGi<span style="font-family: 宋体">对构件化开发进行了很好的支持，当然</span>OSGi<span style="font-family: 宋体">并不为此而生。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">以上所说的构件依赖都是基于</span>API<span style="font-family: 宋体">一级的，那么当然，我们也可以将</span>Web Service<span style="font-family: 宋体">等类型服务封装至构件当中，再结合</span>ESB<span style="font-family: 宋体">，是不是对</span>SOA<span style="font-family: 宋体">的一种更好实现呢！</span>ESB<span style="font-family: 宋体">的关注点在于服务，这是一种细粒度的，它并不考虑服务的封装、重用等方面——这些方面都由设计人员去把握。而结合</span>OSGi<span style="font-family: 宋体">，当然还需要其他设施的支持，比如</span>CXF<span style="font-family: 宋体">已经发布了基于</span>OSGi<span style="font-family: 宋体">的实现，可以将服务封装至一个</span>bundle<span style="font-family: 宋体">，以</span>bundle<span style="font-family: 宋体">为单元，向外界提供服务，这种服务即变成了一种粗粒度的——构件的特点之一。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">综上所述，我相信，</span>OSGi<span style="font-family: 宋体">的发展，将会为构件化的开发方式带来福音。</span></p>
<p style="text-indent: 24pt"><span style="font-family: 宋体">引出话题：</span>OSGi<span style="font-family: 宋体">和</span>SCA<span style="font-family: 宋体">在很多方面有着异曲同工这妙，并且</span>SCA<span style="font-family: 宋体">的实现框架——</span>Tuscany<span style="font-family: 宋体">也对</span>OSGi<span style="font-family: 宋体">做了支持。这两者有互补特性，有时间将对这两者做一个对比研究。</span></p>
 <img src ="http://www.blogjava.net/benniaolk/aggbug/316738.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/benniaolk/" target="_blank">Dreava</a> 2010-03-28 11:49 <a href="http://www.blogjava.net/benniaolk/articles/316738.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSGi初识</title><link>http://www.blogjava.net/benniaolk/articles/316739.html</link><dc:creator>Dreava</dc:creator><author>Dreava</author><pubDate>Sun, 28 Mar 2010 03:47:00 GMT</pubDate><guid>http://www.blogjava.net/benniaolk/articles/316739.html</guid><wfw:comment>http://www.blogjava.net/benniaolk/comments/316739.html</wfw:comment><comments>http://www.blogjava.net/benniaolk/articles/316739.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/benniaolk/comments/commentRss/316739.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/benniaolk/services/trackbacks/316739.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt">OSGi<span style="font-family: 宋体">诞生初期，其目的主要是能够灵活方便并远程管理互联的网络嵌入设备，</span>OSGi<span style="font-family: 宋体">联盟上对于</span>OSGi service platform<span style="font-family: 宋体">有这样一句解释：</span>The OSGi service platform delivers an open, common architecture for service providers, developers, software vendors, gateway operators and equipment vendors to develop, deploy and manage services in a coordinated fashion.<span style="font-family: 宋体">（</span>OSGi service platform<span style="font-family: 宋体">是一个开放并且提供通用接口标准的体系框架，基于这个体系框架，服务提供商，程序开发人员，软件提供商，服务网管运营商，设备提供商能够协调地联合起来开发，部署以及管理向用户提供的各种服务）。随着</span>OSGi<span style="font-family: 宋体">的发展，逐渐被引入到企业应用领域。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">目前，</span>OSGi<span style="font-family: 宋体">规范的最新版本为</span>R4.2<span style="font-family: 宋体">，有关该规范的详细情况请阅读</span>OSGi<span style="font-family: 宋体">实战的第</span>7<span style="font-family: 宋体">节——<a href="/Files/benniaolk/OSGi/OSGi初识/1.pdf"><span style="font-family: 宋体">深入</span>OSGi</a>。</span>OSGi<span style="font-family: 宋体">框架主要分为四部分：运行环境（</span>executionenvironment<span style="font-family: 宋体">）、模块（</span>Modules<span style="font-family: 宋体">）、生命周期管理（</span>Life Cycle<span style="font-family: 宋体">）、服务注册（</span>Service Registry<span style="font-family: 宋体">）。运行在</span>OSGi<span style="font-family: 宋体">环境中的是一个个的</span>Bundle<span style="font-family: 宋体">，也就是</span>Modules<span style="font-family: 宋体">的具体实现。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对于每个</span>bundle<span style="font-family: 宋体">，都有各自的</span>ClassLoader<span style="font-family: 宋体">，在这一点上和传统的</span>Web<span style="font-family: 宋体">应用有相似之处，在传统的</span>Web<span style="font-family: 宋体">应用开发完成之后，都会将其部署在</span>Tomcat<span style="font-family: 宋体">、</span>Jboss<span style="font-family: 宋体">等服务器上，这些</span>Web<span style="font-family: 宋体">应用都有着各自的</span>ClassLoader<span style="font-family: 宋体">环境，而两者之间的区别在于，传统的</span>Web<span style="font-family: 宋体">应用无法做到资源的共享，因为它们是完全独立、隔离的。</span>OSGi<span style="font-family: 宋体">框架为</span>bundle<span style="font-family: 宋体">之间的协作提供了底层支持，通过在</span>bundle<span style="font-family: 宋体">的</span>MANIFEST.MF<span style="font-family: 宋体">文件中</span>Import-Package<span style="font-family: 宋体">、</span>Export-Package<span style="font-family: 宋体">等项，</span>bundle<span style="font-family: 宋体">之间就能相互共享资源及服务，在以后的博文中，我将给出一个具体的示例。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">由于</span>OSGi<span style="font-family: 宋体">具有良好的模块化结构，我个人认为这将为将来的软件开发方式带来很大的冲击，将更进一步推进模块化开发。目前</span>Web<span style="font-family: 宋体">应用的开发一般采用</span>SSH<span style="font-family: 宋体">框架，将整个应用大致分为</span>Web<span style="font-family: 宋体">（负责前台展现）、</span>Service<span style="font-family: 宋体">（负责业务逻辑处理）、</span>DAO<span style="font-family: 宋体">（负责数据持久化）、</span>Domain<span style="font-family: 宋体">（全局实体类）几个模块，而发布的时候，将被一起打成</span>WAR<span style="font-family: 宋体">包，部署至服务器上。如果采取</span>bundle<span style="font-family: 宋体">的形式，每个模块可以做为独立的</span>bundle<span style="font-family: 宋体">进行开发和部署，</span>bundle<span style="font-family: 宋体">之间的协作可以通过上述的方式进行，而这样带来的好处就是，一旦需要对某个模块进行更改，在保证依赖接口不变的前提下，就可以单独更改相应的</span>bundle<span style="font-family: 宋体">，再进行热部署即可，这样一来，好处是显而易见的，有效的分离了各个模块，减少了维护成本。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">由于采用</span>bundle<span style="font-family: 宋体">的形式，也增强了模块的复用性。这也是得益于</span>OSGi<span style="font-family: 宋体">良好的模块化方式。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">另外一个很重要的点就是</span>OSGi<span style="font-family: 宋体">具备热拔插特性，</span>bundle<span style="font-family: 宋体">的安装、启动、停止、卸载都可以在运行时指定，并且可以随时更改。这样一来，我们就可以做到无需重启整个应用，而只对需要更改的部分进行升级或打补丁即可。</span>Bundl<span style="font-family: 宋体">的状态图转换如下图所示：<br />
</span></p>
<p style="text-align: center" align="center"><span style="font-family: 黑体"><img height="372" alt="" src="http://www.blogjava.net/images/blogjava_net/benniaolk/OSGi/OSGi初识/1.JPG" width="458" border="0" /><br />
图</span> 1 OSGi bundle<span style="font-family: 黑体">状态转换图</span></p>
<p style="text-indent: 21.2pt"><span style="font-family: 宋体">以上将</span>OSGi<span style="font-family: 宋体">的一些基本的，但也是很重要的东西大概介绍了一下，在以后的博文中逐步深入吧。以上都是关于</span>OSGi<span style="font-family: 宋体">原理性的东西，那么实现该规范的有哪些产品呢？最有名的应该要数</span>Eclipse<span style="font-family: 宋体">的</span>Equinox<span style="font-family: 宋体">框架了，在网上查资料见有人说过，</span>Eclipse3.0<span style="font-family: 宋体">的那一次升级把自身的构架做了一次非常大的调整，其主要原因就是采用了</span>OSGi<span style="font-family: 宋体">框架，更好的支持了</span>Eclipse<span style="font-family: 宋体">的插件体系。另外还有</span>Felix<span style="font-family: 宋体">、</span>knopflerfish<span style="font-family: 宋体">等。</span></p>
<p style="text-indent: 21.2pt"><span style="font-family: 宋体">不过话说回来，尽管</span>OSGi<span style="font-family: 宋体">有很多好处，但是现在主要还是应用在服务器端，如现在的应用服务器基本上都采用</span>OSGi<span style="font-family: 宋体">的框架，而真正的应用市场仍处理起步阶段，这和</span>OSGi<span style="font-family: 宋体">的生态环境还不成熟，可喜的是</span>Spring<span style="font-family: 宋体">推出了其</span>Spring DM<span style="font-family: 宋体">和</span>SpringSource DM Server<span style="font-family: 宋体">，前者能够很方便发布和引用服务，并且与</span>Spring Framework<span style="font-family: 宋体">平台相融合，将</span>OSGi<span style="font-family: 宋体">的</span>bundle context<span style="font-family: 宋体">与</span>Spring&nbsp;applicationContext<span style="font-family: 宋体">融合在一起，大大方便了</span>OSGi<span style="font-family: 宋体">的应用。后者是</span>OSGi bundle<span style="font-family: 宋体">的运行环境，是一个将</span>Equinox<span style="font-family: 宋体">和</span>Tomcat<span style="font-family: 宋体">融合在一起的服务器。在以后的博文中将详细介绍这些内容。</span></p>
 <img src ="http://www.blogjava.net/benniaolk/aggbug/316739.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/benniaolk/" target="_blank">Dreava</a> 2010-03-28 11:47 <a href="http://www.blogjava.net/benniaolk/articles/316739.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>