以正确的方式实现白板模式?

nad*_*har 1 java osgi

请考虑以下来自http://www.knopflerfish.org/osgi_service_tutorial.html#best解释白板模式的代码片段

ServiceListener sl = new ServiceListener() {
public void serviceChanged(ServiceEvent ev) {
  ServiceReference sr = ev.getServiceReference();
  switch(ev.getType()) {
  case ServiceEvent.REGISTERED:
    {
          registerServlet(sr);
    }
    break;
  case ServiceEvent.UNREGISTERING:
    {
          unregisterServlet(sr);
    }
    break;
  }
}
  };

String filter = "(objectclass=" + HttpServlet.class.getName() + ")";
try {
  bc.addServiceListener(sl, filter); // -- 1
  ServiceReference[] srl = bc.getServiceReferences(null, filter); // -- 2
  for(int i = 0; srl != null && i < srl.length; i++) {
sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED,
                   srl[i]));
  }
} catch (InvalidSyntaxException e) { 
  e.printStackTrace(); 
}
Run Code Online (Sandbox Code Playgroud)

是否有可能在第1行和第2行之间复制ServiceEvent.REGISTERED事件?在第1行和第2行之前注册服务侦听器后,服务注册自身,导致侦听器接收ServiceEvent.REGISTERED通知.在所有服务引用中的第2行是对该服务的引用,导致通知被接收两次.这种情况可能吗?如果是,那么可以采取哪些措施来避免这种情况?

BJ *_*ave 6

使用ServiceTracker而不是尝试使用"原始"API执行此操作.ServiceTracker将为您正确处理这些问题.

更好的是使用声明式服务.