当多个Bundle使用同一接口名注册服务时,服务的获取策略如下:OSGi容器会返回排行最高的服务,即,返回注册时SERVICE_RANKING属性值最大的服务。如果有多个服务的排行值相等,那么OSGi容器将返回PID值最小的那个服务。
如果服务消费者需要对服务进行跟踪,比如服务何时被注册,何时取消注册等,可以使用ServiceTracker类。以下是该类的使用范例源码:
1、接口及其实现类:
public interface HelloService {
public String sayHello(String name);
}
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "Hello " + name;
}
}
2、服务跟踪器子类
/**
* 服务跟踪器:跟踪注册到HelloService接口下的所有服务
*/
public class HelloServiceTracker extends ServiceTracker {
public HelloServiceTracker(BundleContext context){
super(context, HelloService.class.getName(), null);
}
@Override
public Object addingService(ServiceReference reference) {
System.out.println("adding service: " + reference.getBundle().getSymbolicName());
return super.addingService(reference);
}
@Override
public void removedService(ServiceReference reference, Object service) {
System.out.println("removed service: " + reference.getBundle().getSymbolicName());
super.removedService(reference, service);
}
}
3、Bundle激活器类
public class Activator implements BundleActivator {
HelloServiceTracker helloServiceTracker;
ServiceRegistration serviceRegistration;
public void start(BundleContext context) throws Exception {
System.out.println("start...");
//启动服务跟踪器
helloServiceTracker = new HelloServiceTracker(context);
helloServiceTracker.open();
//注册服务
serviceRegistration = context.registerService(HelloService.class.getName(), new HelloServiceImpl(), null);
//获取被跟踪的服务
HelloService helloService = (HelloService)helloServiceTracker.getService();
if(helloService!=null){
System.out.println(helloService.sayHello("cjm"));
}
}
public void stop(BundleContext context) throws Exception {
System.out.println("stop");
//关闭服务跟踪器
helloServiceTracker.close();
serviceRegistration.unregister();
}
}
4、运行结果
osgi>
start...
adding service: p1
Hello cjm
osgi> stop 86
stop
removed service: p1