1、Dictionary Client Service
在此例子中,我们在 Bundle 启动的使用使用 context 查询已经注册的字典服务列表,并且使用服务列表的第一个字典服务查询输入的单词是否正确,并且输出简单的匹配结果,当用户没有输入的时候,则会退出字典的查询。我们通过 Java 接口的方式使用OSGI 的服务,这也是我们经常提到的面向对象语言降低模块之间耦合度的一种方式:面向接口编程,具体代码如下:
/*
* Apache Felix OSGi tutorial.
**/
package tutorial.example3;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import tutorial.example2.service.DictionaryService;
/**
* 在启动的时候使用 DictionaryService 检查输入的单词是否正确,并且打印初相应的检测结果,
* 但是在代码中并没有解决服务的状态动态改变的问题,例如服务注册或者注销,代码不够健壮,
* 此例子的初衷在于如何在 bundle 中查询服务,并且使用,更加完善的代码会在后面的例子中给出。
* 注意:当我们没有输入任何信息的时候,单词检测便会结束,如果需要重新进入单词检测程序,我们
* 只能重启此 bundle。
**/
public class Activator implements BundleActivator
{
/**
* Implements BundleActivator.start(). Queries for
* all available dictionary services. If none are found it
* simply prints a message and returns, otherwise it reads
* words from standard input and checks for their existence
* from the first dictionary that it finds.
* (NOTE: It is very bad practice to use the calling thread
* to perform a lengthy process like this; this is only done
* for the purpose of the tutorial.)
* @param context the framework context for the bundle.
**/
public void start(BundleContext context) throws Exception
{
// Query for all service references matching any language.
ServiceReference[] refs = context.getServiceReferences(
DictionaryService.class.getName(), "(Language=*)");
if (refs != null)
{
try
{
System.out.println("Enter a blank line to exit.");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String word = "";
// Loop endlessly.
while (true)
{
// Ask the user to enter a word.
System.out.print("Enter word: ");
word = in.readLine();
// If the user entered a blank line, then
// exit the loop.
if (word.length() == 0)
{
break;
}
// First, get a dictionary service and then check
// if the word is correct.
DictionaryService dictionary =
(DictionaryService) context.getService(refs[0]);
if (dictionary.checkWord(word))
{
System.out.println("Correct.");
}
else
{
System.out.println("Incorrect.");
}
// Unget the dictionary service.
context.ungetService(refs[0]);
}
} catch (IOException ex) { }
}
else
{
System.out.println("Couldn't find any dictionary service...");
}
}
/**
* Implements BundleActivator.stop(). Does nothing since
* the framework will automatically unget any used services.
* @param context the framework context for the bundle.
**/
public void stop(BundleContext context)
{
// NOTE: The service is automatically released.
}
}
构建 manifest.mf:
Bundle-Name: Dictionary client
Bundle-Description: A bundle that uses the dictionary service if it finds it at startup
Bundle-Vendor: Apache Felix
Bundle-Version: 1.0.0
Bundle-Activator: tutorial.example3.Activator
Import-Package: org.osgi.framework,
tutorial.example2.service
编译、打包:
D:\devInstall\apache\felix-framework-6.0.0\examples\demo03\src> javac -cp ..\..\demo02\target\example2.jar;..\..\..\bin\felix.jar -encoding UTF-8 -d ..\target\ .\tutorial\example3\*.java
D:\devInstall\apache\felix-framework-6.0.0\examples\demo03\src> cd ../target
D:\devInstall\apache\felix-framework-6.0.0\examples\demo03\src> cp ../src/mainfest.mf ./
D:\devInstall\apache\felix-framework-6.0.0\examples\demo03\src> jar cvfm ./manifest.mf -C . .
已添加清单
正在添加: manifest.mf(输入 = 285) (输出 = 182)(压缩了 36%)
正在添加: tutorial/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: tutorial/example3/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: tutorial/example3/Activator.class(输入 = 1795) (输出 = 1008)(压缩了 43%)
安装、运行:
g! install file:./examples/demo03/target/example3.jar 11:09:06
Bundle ID: 11
g! start 11 11:09:30
Enter a blank line to exit.
Enter word: Incorrect.
Enter word: Incorrect.
Enter word: ~ g! lb 11:09:42
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (6.0.0)|6.0.0
1|Active | 1|jansi (1.17.1)|1.17.1
2|Active | 1|JLine Bundle (3.7.0)|3.7.0
3|Active | 1|Apache Felix Bundle Repository (2.0.10)|2.0.10
4|Active | 1|Apache Felix Gogo Command (1.0.2)|1.0.2
5|Active | 1|Apache Felix Gogo JLine Shell (1.1.0)|1.1.0
6|Active | 1|Apache Felix Gogo Runtime (1.1.0)|1.1.0
7|Active | 1|Service listener example (1.0.0)|1.0.0
8|Active | 1|English dictionary (1.0.0)|1.0.0
10|Active | 1|French dictionary (1.0.0)|1.0.0
11|Active | 1|Dictionary client (1.0.0)|1.0.0
g!
当 bundle 安装、启动的时候,其会在 OSIG 框架下寻找所有的字典服务实现,然后使用第一个实现对输入的单词做检测,并输出检测结果,当没有任何输入的时候,则检测结束。
对于上面的例子,也许许多的读者会很好奇当字典服务被注销了会发生什么事情?当系统里面的所有字典服务被注销的时候,则在问我们在尝试访问服务对象的时候发生空指针异常,这种服务对象的状态在动态变化是常有的情况,而且此种情况应该如何处理也是我们特别关注的问题,在之后介绍的例子中将会解决类似的问题。