2016-11-02 3 views

ответ

2

Я почти во всех случаях пользуюсь сервис-трекером. Мне нужно выполнить некоторую уборку, связанную с отслеживаемым объектом. Когда гусеничный объект уходит, эта информация об уборка должна быть собрана мусором.

Так, например, вы отслеживаете 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()); 
    } 
} 

Я редко использую Service Tracker в настоящее время, так как декларативные услуги делают работу в большинстве случаев намного проще. Однако, когда я использую Service Tracker, у меня редко бывает S == T

1

Отслеживаемый объект позволяет вам выполнять любое необходимое обслуживание, когда служба снова удаляется.

В качестве примера см. trackers in pax-jdbc. В этом случае нам нужны две службы. PooledDataSourceFactoryTracker запустит другой трекер для DataSourceFactory. Этот второй трекер является отслеживаемым объектом первого трекера. Когда PooledDataSourceFactory снова удаляется, другой трекер DataSourceFactory также закрыт.

Этот подход позволяет отслеживать несколько сервисов или выполнять другие операции по удалению обслуживания без необходимости использования резьбы.

Помните, что даже при таком подходе сервисные трекеры очень трудно использовать правильно. В большинстве случаев с самого начала лучше использовать инфраструктуру, такую ​​как декларативные услуги.

1

T позволяет отслеживать другой тип, чем этот тип обслуживания S. Например, вы можете обернуть службу S в объект типа T. Для большинства случаев использования S и T являются одинаковыми. Но есть случаи, когда T! = S.

+0

Значит ли это, что T должен быть подклассом S? Потому что, если я зарегистрирую S как услугу, как я могу получить T ?. Можете ли вы привести пример, когда T! = S – ares

+0

Нет, T не нужно связывать с S. Я думаю, что я уже привел пример, где T - некоторый объект, который обертывает S: новый T (S). Другие ответы от Кристиана Шнайдера и Питера Кринса также приводят примеры, где Т не является S. –

Смежные вопросы