osgi + felix example3编写与使用服务的改进
Posted 叶长风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了osgi + felix example3编写与使用服务的改进相关的知识,希望对你有一定的参考价值。
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中一些深入的概念以及一些中间件的使用。
以上是关于osgi + felix example3编写与使用服务的改进的主要内容,如果未能解决你的问题,请参考以下文章