-
Notifications
You must be signed in to change notification settings - Fork 0
Felix_Tutorial_2b
示例二之二 —— 辞典服务程序包的替代品
本示例程序创建了示例二中定义的辞典服务的一个替代品。程序包的源代码基本上相同除了使用法语词汇替换了英语词汇。另外的不同点仅仅是我们不需要在这个程序包中再次定义辞典服务接口,因为我们可以从示例二中直接引用。这个例子的主要目的是一个服务可以同时存在多个实现。我们同样会在示例五中使用本例。
在下面的源代码中,程序包使用它运行时的上下文环境注册这个辞典服务。我们在这个程序包的接口中以内部类的形式实现这个辞典服务,但我们同样可以将其放到单独的文件中。我们的程序包的源代码如下,存储在文件Activator.java中。
/* * Apache Felix OSGi 教程. **/
package tutorial.example2b;
import java.util.Properties;
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceEvent;
import tutorial.example2.service.DictionaryService;
/ * 此类实现了使用程序包的上下文环境向OSGi框架注册法语辞典服务的程序包。 * 此辞典服务的接口定义在单独的文件中而且被一个内部类实现。 * 此类除了辞典中包含的是法语词汇外其他方面同示例二中的类类似。 / public class Activator implements BundleActivator { / * 实现BundleActivator.start()方法。使用软件包运行时的上下文环境 * 注册辞典服务的一个实例, * 并且附上查找相关服务时可以用来定位到此服务的一些属性。 * @param context 程序包运行时在框架中所处的上下文环境 / public void start(BundleContext context) { Properties props = new Properties(); props.put("Language", "French"); context.registerService( DictionaryService.class.getName(), new DictionaryImpl(), props); }
/** * 实现BundleActivator.stop()方法。因为框架会自动注销任何注册的服务,所以在这里不做任何操作。 * @param context 程序包运行时在框架中所处的上下文环境 **/ public void stop(BundleContext context) { // 注意: 服务会自动注销 }
/** * 实现辞典服务的内部类。 * 若要了解此服务的详细情况请查看DirectoryService。 **/ private static class DictionaryImpl implements DictionaryService { // 辞典里包含的一组词 String[] m_dictionary = { "bienvenue", "au", "tutoriel", "osgi" };
/** * 实现DictionaryService.checkWord()方法。检查传入的 * 词是否收录在辞典里。 * @param word 需要检查的词 * @return 如果传入的词收录在辞典里,返回true * 否则返回false **/ public boolean checkWord(String word) { word = word.toLowerCase();
// This is very inefficient for (int i = 0; i < m_dictionary.length; i++) { if (m_dictionary[i].equals(word)) { return true; } } return false; } } }
我们必须创建包含我们程序包的导引信息的manifest.mf文件,这个描述文件包含如下内容:
Bundle-Name: French dictionary Bundle-Description: A bundle that registers a French dictionary service Bundle-Vendor: Apache Felix Bundle-Version: 1.0.0 Bundle-Activator: tutorial.example2b.Activator Import-Package: org.osgi.framework, tutorial.example2.service
我们指明哪一个类实现了Bundle-Activator属性指定的接口,而且指明我们的程序包引入了OSGi核心程序包并且指明了通过Import- Package属性引入的辞典服务接口包。辞典服务接口包会部署在导出了此包的示例二中。(提示:确信你的manifest文件尾部以回车结束,否则最后一行会被忽略)
为了编译这个源文件时我们需要在classpath中加入felix.jar文件(可以在felix套件的bin目录下找到),我们用下面的命令编译源文件:
javac -d c:\classes *.java
此命令会编译所有的源文件并且把生成的类文件输出到c:\classes目录中一个子目录下,这个子目录就是tutorial\example2b,按照我们在源文件中制定的包名命名。为了让以上命令能够正常执行,目录c:\classes必须存在。编译后,我们必须创建一个JAR文件以包装生成的包目录,且要将包含软件包导引信息的描述文件一并添加到JAR包中。我们使用如下命令创建这个JAR文件:
jar cfm example2b.jar manifest.mf -C c:\classes tutorial\example2b
此命令利用我们创建的描述文件创建了一个JAR包而且包含了在c:\classes目录下的tutorial\example2b目录中所有的类文件。当此JAR文件成功创建后,我们便可以准备安装并且启动此程序包。
我们按照usage.html中描述的步骤启动Felix,当我们启动Felix后,程序会询问一个档案名,我们可以将我们所有的程序包置入一个名为 "tutorial"的档案中。当Felix启动後,我们应该确认示例一中的程序包是有效的(active)。我们可以使用Felix的 shell命令 -Y´ps¡获取所有程序包的列表,以及它们的状态和标记值。如果示例一的程序包不是有效的,我们必须使用start命令和´ps¡命令打印出的那个标记值将其启动。现在我们可以安装并且启辞典服务程序包。假如我们的把我们的程序包创建在c:\tutorial。我们可以在Felix shell中使用如下方法将其安装并且启用:
start file:/c:/tutorial/example2b.jar
上述命令可以在一个步骤里安装并启动这个软件包,同时也可以使用install和start两个命令分两步安装并启动此软件包。如果要停掉此程序包,可以使用Felix的stop命令,如果示例一的程序包仍然处於有效的状态,则我们可以看到当我们的程序包注册其辞典服务时会打印出接收到的服务事件的详细信息。使用Felix shell的´ps¡命令获取我们的辞典服务程序包的标记值,并且我们可以分别使用stop和restart命令将其停掉和重新启动。每次我们打开和关闭我们的辞典服务程序包。我们可以看到示例一中程序打印出的相关服务事件的详细信息。在示例三中,我们会为我们的辞典服务制作一个客户端。如果想要离开 Felix,使用shutdown命令。