在OSGi中,被跟踪的服务类型与被跟踪对象的类型之间有什么区别

时间:2016-11-02 07:50:14

标签: java osgi

在OSGi中,类ServiceTracker定义了两个类型参数:

  1. S - 正在跟踪的服务类型。
  2. T - 跟踪对象的类型。
  3. 他们两个有什么区别?

3 个答案:

答案 0 :(得分:3)

在几乎所有情况下,我都使用服务跟踪器,我需要做一些与被跟踪对象相关的内务处理。当被跟踪的物体消失时,该管家信息应该被垃圾收集。

例如,您跟踪WhiteboardListeners。但是,您希望跟踪它们用于回调的时间长度,如果它们使用太多时间则拒绝它们服务。所以我们创建一个包装器:

public class Example {

  interface Whiteboard {
    void visit();
  }

  static class Wrapper {
    Whiteboard  whiteboard;
    AtomicLong  averageTime = new AtomicLong();

    public Wrapper(Whiteboard whiteboard) {
        this.whiteboard = whiteboard;
    }

    void visit() {
        if (averageTime.get() < 100) {
            long start = System.currentTimeMillis();
            whiteboard.visit();
            long time = System.currentTimeMillis() - start;
            averageTime.getAndUpdate(v -> (99 * v + time) / 100);
        } else
            averageTime.getAndUpdate(v -> (99 * v) / 100);
    }
  }

  ServiceTracker<Whiteboard, Wrapper> tracker;

  @Activate
  void activate(BundleContext context) {
      tracker = new ServiceTracker<Whiteboard, Wrapper>(context,
            Whiteboard.class, null) {
        @Override
        public Wrapper addingService(
                ServiceReference<Whiteboard> reference) {
            return new Wrapper(context.getService(reference));
        }

        @Override
        public void removedService(ServiceReference<Whiteboard> reference,
                Wrapper service) {
            context.ungetService(reference);
        }
    };
    tracker.open();
  }

  void visit() {
    tracker.getTracked().values().forEach(wrapper -> wrapper.visit());
  }
}

我现在很少使用服务跟踪器,因为声明服务在大多数情况下更容易完成工作。但是,当我使用服务跟踪器时,我很少有S==T

答案 1 :(得分:1)

跟踪对象允许您在再次删除服务时进行任何必要的内务管理。

作为示例,请参阅trackers in pax-jdbc。在这种情况下,我们需要两个服务。 PooledDataSourceFactoryTracker将为DataSourceFactory启动另一个跟踪器。该第二跟踪器是第一跟踪器的跟踪对象。当再次删除PooledDataSourceFactory时,其他DataSourceFactory跟踪器也会关闭。

此方法允许跟踪多个服务或执行其他服务删除,而无需处理线程。

请注意,即使采用这种方法,服务跟踪器也很难正确使用。在大多数情况下,最好从一开始就使用声明式服务等框架。

答案 2 :(得分:1)

T可让您跟踪与该服务类型S不同的类型。例如,您可以将服务S包装在T类型的对象中。对于大多数用例,ST都是相同的。但是有一些用例T != S