研究OSGI也有点时间了,想把学到的东西记录下来,当作学习笔记吧
今天我们来看下OSGI中的服务注册方法,还是通过一个简单的例子来说明怎么使用吧
首先我们先新建一个使用HelloWorld模板的RCP项目,
项目建好了,文件结构如下图所示:
打开 Activator .java 这个类,下面我们主要是对这个类进行扩展,先说一下,这个类是负责插件的加载和卸载功能,控制插件的生命周期。先定位到 start 方法,我们在这个方法中先注册服务,然后在读取刚才注册的服务,我们先新建一个org.vwpolo.osgi.service.client.service 的包,然后在新增一个接口和两个类,IUserService.java、UserServiceImpl.java和UserServiceFactory.java;
IUserService.java这个接口是定义服务的方法,类的内容如下所示:
/**
* <p>用户服务接口。</p>
* @author 刘尧兴
* <p>2008-2-13</p>
*/
public interface IUserService {
/**
* <p>取得名称。</p>
* @author 刘尧兴
* @return
*/
public String getName();
/**
* <p>关闭服务。</p>
* @author 刘尧兴
*/
public void close();
}
为了简单起见,这个类只有两个方法,一个是获得User名称,另外一个是关闭服务
UserServiceImpl.java 这个类实现了 IUserService 这个接口,实现接口中的功能
public class UserServiceImpl implements IUserService {
@Override
public String getName() {
return " VWPOLO " ;
}
@Override
public void close() {
System.out.println( " 服务已关闭! " );
}
}
同样,这个类也很简单,关于 UserServiceFactory.java这个类的作用我们等下在来解释它
下面我们来完善 Activator 这个类,我们在 start方法中 加入 registerUserService 方法和 loadUserService 方法, registerUserService 方法是负责向OSGI注册IUserService用户服务,而 loadUserService 是通过OSGI来获得IUserService服务,并调用其中的方法
super .start(context);
plugin = this ;
this .context = context;
registerUserService();
loadUserService();
}
//这个方法在插件被加载的时候调用,我们通过这个方法来注册用户服务和使用用户服务
* <p>注册用户服务。</p>
* @author 刘尧兴
*/
private void registerUserService() {
Hashtable properties = new Hashtable( 7 );
properties.put(Constants.SERVICE_VENDOR, " VWPOLO " );
properties.put(Constants.SERVICE_DESCRIPTION, " 一个使用OSGI注册服务的简单例子 " );
properties.put(Constants.SERVICE_PID, IUserService. class .getName());
userService = context.registerService(IUserService. class .getName(), new UserServiceFactory(), properties);
}
//这个方法的作用是注册用户服务,在这里我们根据指定的属性和指定的服务对象向OSGI框架注册这个服务,
第一个参数是要加载的服务对象的完整路径名称,根据面向接口编程的原则,我们这里的服务名称为接口的名称,方便扩展
第二个参数为服务对象,这样这个服务对象或是 ServiceFactory 的子类, ServiceFactory 类允许我们向OSGI环境提供自定义的服务对象,在这里我们通过 UserServiceFactory 类 扩展 ServiceFactory 这个类, UserServiceFactory 类的内容为:
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceRegistration;
public class UserServiceFactory implements ServiceFactory ... {
/**//*
* 创建一个新的服务对象
* OSGI框架会先通过Bundle使用BundleContext.getService(ServiceReference)方法请求一个服务对象
* 这个工厂类会提供一个指定的服务给每个调用的Bundle
* @author 刘尧兴
*/
@Override
public Object getService(Bundle bundle, ServiceRegistration registration) ...{
return new UserServiceImpl();
}
/**//*
* 关闭服务对象
* 当框架要关闭服务的时候会调用这个方法
* @author 刘尧兴
*/
@Override
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) ...{
((IUserService)service).close();
}
}
/** */ /**
* <p>加载用户服务并使用。</p>
* @author 刘尧兴
*/
private void loadUserService() ... {
ServiceReference reference = null;
try ...{
reference = context.getServiceReference(IUserService.class.getName());
if(reference == null)
return;
IUserService userService = (IUserService) context.getService(reference);
System.out.println(userService.getName());
}catch (Exception e) ...{
e.printStackTrace();
}
}
这个方法是向OSGI框架请求一个服务(UserService),并调用其中实现的方法
下面是这个类的完整源代码:
import java.util.Hashtable;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.vwpolo.osgi.service.client.service.IUserService;
import org.vwpolo.osgi.service.client.service.UserServiceFactory;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = Activator. class .getPackage().getName();
// The shared instance
private static Activator plugin;
/**
*
*/
private BundleContext context;
/**
*
*/
private ServiceRegistration userService;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super .start(context);
plugin = this ;
this .context = context;
registerUserService();
loadUserService();
}
/**
* <p>注册用户服务。</p>
* @author 刘尧兴
*/
private void registerUserService() {
Hashtable properties = new Hashtable( 7 );
properties.put(Constants.SERVICE_VENDOR, " VWPOLO " ); // $NON-NLS-1$
properties.put(Constants.SERVICE_DESCRIPTION, " 一个使用OSGI注册服务的简单例子 " );
properties.put(Constants.SERVICE_PID, IUserService. class .getName());
userService = context.registerService(IUserService. class .getName(), new UserServiceFactory(), properties);
}
/**
* <p>加载用户服务并使用。</p>
* @author 刘尧兴
*/
private void loadUserService() {
ServiceReference reference = null ;
try {
reference = context.getServiceReference(IUserService. class .getName());
if (reference == null )
return ;
IUserService userService = (IUserService) context.getService(reference);
System.out.println( " 服务名称: " + userService.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null ;
super .stop(context);
userService.unregister();
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}
现在我们来看下效果吧:
可以看到控制台输出我们调用服务接口的方法结果,当我们退出这个RCp程序时会发现控制台已经输出了服务已关闭的信息