OSGi - 第04章 BundleContext.getService()详解之二

这一节对比一下BundleContext上几个getServiceReference方法的差别:




1、getAllServiceReferences(String clazz, String filter)方法:

      这个方法从服务注册表中检索所有以指定服务名称注册的服务,并且按照服务过滤条件进行过滤。

      这里需要注意2点:一是服务注册时,可选提供一些服务属性,那么在服务检索时,可以根据

      服务属性进行过滤。其中,服务注册时对应的ClassName,也被作为一条属性存储:

      即:Constants.OBJECTCLASS = {className} ,所以:

      getServiceReference("demo.Foo", null)  等价于 getServiceReference(null, "(objectClass=demo.Foo)")


      二是不同构件、或者同一个构件可以使用相同的className来注册多个服务,对于某一个服务客户端来说,

      服务客户端对其中的部分服务可能是不可见的。这儿的“不可见”取决于ClassLoader的委托关系。

      这是构件从Installed状态变成Resolved状态时就已经确定的。

      注意,对于getAllServiceReferences方法,是不做可见性过滤的。如果你明确服务是单一的,不会存在可见性问题,就可以忽略这种可见性问题。

      当然,这儿的不可见是指影响赋值时的强制类型转换(会报Class cast之类的错误),但不影响反射方式使用对象。


2、getServiceReferences(Class<S> clazz, String filter)方法:

      和上一个方法的唯一区别就是在上一个方法的调用结果上, 再添加一层可见性检查。

      可见性检查通过调用:ServiceReference.isAssignableTo(Bundle bundle, String className)方法实现。


3、getServiceReferences(String clazz, String filter)方法:

      和上一个方法想同,唯一的差别是,一个返回数组、一个返回集合。(有点冗余的方法)


4、getServiceReference(Class<S> clazz)方法:

      在getServiceReferences方法的基础上,挑选一个最佳服务返回;

      那么最佳服务如何选择呢?请看ServiceReference.compareTo方法的说明:


      即:在服务注册时,可以提供一个SERVICE_RANKING( "service.ranking")属性,用来指明服务优先级,

      如果未指定的话,缺省优先级为 0 

      如果两个服务优先级相同(比如,都没有指定,都是0),那么它们的优先级取决于SERVICE_ID(即service.id),

     这是在注册服务时,由框架自动生成的,取决于服务注册的先后次序。


5、getServiceReference(String clazz)方法:

     和上一个方法相同,只是参数形式差异而已。


6、说完了getServiceReferences、和getAllServiceReferences的区别,

      同样的,这样的差别在ServiceTracker中也有,差别反映在ServiceTracker的两个open方法上:

      看下面代码就明白了:

	public void open() {
		open(false);
	}
	public void open(boolean trackAllServices) {}
       缺省的open方法并非跟踪所有服务,也就意味着对服务的可见性进行过滤;

       等价于open(false)的效果。

       显式调用open(true)即可对省去服务可见性过滤操作,如果服务数量庞大,服务可见性过滤会消耗较多时间,对性能产生一定的影响。

7、再扯一下和服务相关的两个看上去容易混淆的单词:

	String	SERVICE_ID								= "service.id";
	String	SERVICE_PID								= "service.pid";
      其中,service.id是由框架在运行时动态产生的一个唯一的序列号;

      作用之一就是上面的寻找最佳匹配服务之时;

      而service.pid是一个由服务提供者注册服务时自己设定的属性。它用来标识一个持久化的、可在多次JVM启动期间

      都可以唯一匹配到的标识。

      作用之一是用于OSGi的配置管理服务。框架在启动时从持久化存储中拿到一份配置信息时,可以知道它属于哪个服务所有。

      从而可以通知该服务对象更新配置。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值