您的位置:首页 > Web前端

osgi + felix example3编写与使用服务的改进

2016-07-01 07:57 309 查看

osgi + felix example3编写与使用服务的改进

上一篇博文中我们提及了如何对一个服务进行注册,但在example2和example2b中都没有对这个服务进行相应的使用,在本文中将对这个服务进行使用相应的使用,在felix的官网中,对该服务的使用方法是对目前已经注册的bundle进行扫描,然后使用服务,但是个人觉得Activator这种启动bundle最好只有一个,并且本文搭建了一个完整的环境,部署多个Activator bundle也不现实,因此本文采用了其他方法。

思路

在本文中,考虑的实现是在Bundle中再实现一次DictionaryService接口,然后在Activator中的start方法中进行这个服务的注册,并在随后的程序中进行相应的服务使用,不在对其他bundle进行扫描获取服务。

程序

之前的DictionaryService不再展示出来,在改动后的程序为:

package cn.com.example4;

import cn.com.example2.DictionaryService;
import org.osgi.framework.*;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;

/**
* Created by Administrator on 2016/6/19.
*/
public class Activator implements BundleActivator, ServiceListener {

//Bundle's context
private BundleContext m_context = null;
//The service reference being used.
private ServiceReference m_ref = null;
//The service object being used.
private DictionaryService m_dictionary = null;

public void start(BundleContext context) throws Exception {
m_context = context;
Hashtable<String, String> props = new Hashtable<String, String>();
props.put("Language", "French");
context.registerService(DictionaryService.class.getName(), new DictionaryImpl(), props);
synchronized (this) {
m_context.addServiceListener(this,  "(&(objectClass=" + DictionaryService.class.getName() + ")" +
"(Language=*))");
//Query for any service references matching any language.
ServiceReference[] refs = m_context.getServiceReferences(DictionaryService.class.getName(), "(Language=*)");
//If we found any dictionary services, then just get
//a reference to the first one so we can use it.
if (refs != null) {
m_ref = refs[0];
m_dictionary = (DictionaryService)m_context.getService(m_ref);
}
}
try {
System.out.println("Enter a blank line to exit.");
String word = "";
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
//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;
} else if (m_dictionary == null) {
System.out.println("No dictionary available");
} else if (m_dictionary.checkWord(word)) {
System.out.println("Correct.");
} else {
System.out.println("Incorrect.");
}
}
} catch (Exception e) {

}
}

public void stop(BundleContext context) throws Exception {

}

public void serviceChanged(ServiceEvent event) {
String[] objectClass = (String[]) event.getServiceReference().getProperty("objectClass");
// If a dictionary service was registered, see if we
// need one. If so, get a reference to it.
if (event.getType() == ServiceEvent.REGISTERED)
{
if (m_ref == null)
{
// Get a reference to the service object.
m_ref = event.getServiceReference();
m_dictionary = (DictionaryService) m_context.getService(m_ref);
}
}
// If a dictionary service was unregistered, see if it
// was the one we were using. If so, unget the service
// and try to query to get another one.
else if (event.getType() == ServiceEvent.UNREGISTERING) {
if (event.getServiceReference() == m_ref) {
// Unget service object and null references.
m_context.ungetService(m_ref);
m_ref = null;
m_dictionary = null;

// Query to see if we can get another service.
ServiceReference[] refs = null;
try {
refs = m_context.getServiceReferences(
DictionaryService.class.getName(), "(Language=*)");
} catch (InvalidSyntaxException ex) {
// This will never happen.
}
if (refs != null) {
// Get a reference to the first service object.
m_ref = refs[0];
m_dictionary = (DictionaryService) m_context.getService(m_ref);
}
}
}
}

private static class DictionaryImpl implements DictionaryService {

String[] m_dictionary = {
"bienvenue", "au", "tutoriel", "osgi"
};

public boolean checkWord(String word) {
word = word.toLowerCase();
for (int i = 0;i < m_dictionary.length; i++) {
if (m_dictionary[i].equals(word)) {
return true;
}
}
return false;
}
}
}


在这个程序中,

context.registerService(DictionaryService.class.getName(), new DictionaryImpl(), props);


这段代码进行我们服务的注册,在以下一段代码中,我们进行了获取服务:

ServiceReference[] refs = m_context.getServiceReferences(DictionaryService.class.getName(), "(Language=*)");
m_dictionary = (DictionaryService)m_context.getService(m_ref);


如此,我们就可以使用相关的服务了。

程序运行

在程序启动之前,首先需要pom.xml中felix插件的Bundle-Activator的启动类,改为当前类后可以正常启动,现在运行程序观察结果:



可以观察到服务正常启动,输入osgi,显示结果为:



可以得到响应,说明服务正常提供,注册服务与使用服务均成功。

总结

在以上服务进行相应的注册并使用,使用osgi传统的注册式服务是比较简单与方便的,但个人认为在Bundle中还是不要使用这种方式不断的注册服务和使用服务,这里的接口实现类最好还是不要放在Bundle内部,单独抽出来。

在下节的编写中,将不再讲解felix官网的这些简单示例,将开始blueprint的讲解,同时这些服务的使用将会使用blueprint来管理,不再使用osgi的注册式服务与声明式服务。

在后续的博文中,将开始osgi中一些深入的概念以及一些中间件的使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: