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 框架下尋找所有的字典服務實現,然後使用第一個實現對輸入的單詞做檢測,並輸出檢測結果,當沒有任何輸入的時候,則檢測結束。
對於上面的例子,也許許多的讀者會很好奇當字典服務被註銷了會發生什麼事情?當系統裏面的所有字典服務被註銷的時候,則在問我們在嘗試訪問服務對象的時候發生空指針異常,這種服務對象的狀態在動態變化是常有的情況,而且此種情況應該如何處理也是我們特別關注的問題,在之後介紹的例子中將會解決類似的問題。