当多个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