Как работает жизненный цикл компонентов DS?

В каком порядке вызываются аннотированные методы при запуске и остановке пакета?

Я использую аннотации aQute.bnd.annotation.

Есть ли документация по этому поводу?

Я предполагаю, что это: при запуске пакета:

  1. SetA
  2. onStartUp (@Активировать)

при остановке пакета:

  1. unsetA
  2. onShutdown (@Деактивировать)

Мне нужен метод, который вызывается после того, как все сервисные ссылки на компонент сброшены. Могу ли я использовать для этого метод @Deactivate?

@Component(immediate=true)
public class AImpl implements A {

    @Activate
    public void onStartUp() {

    }

    @Deactivate
    public void onShutDown() {

    }

}


public class B {


private A a;

@Reference(name = "a", 
    service = A.class,  
    optional = false,
    multiple = false,
    dynamic = true,
    unbind = "unsetA")
    public void setA(A a) {
        this.a = a;
    }

    public void unsetA(A a) {
        this.a = null;
    }

}

person Felix Schmidt    schedule 22.09.2014    source источник


Ответы (1)


Жизненный цикл указан в главе «Декларативные службы» спецификации компендиума OSGi. Хотя вы используете аннотации, создается XML, и DS работает на основе XML.

В случае, если компонент остановлен, метод @Deactivate вызывается до сброса ссылок. Вы используете динамическую ссылку, поэтому может случиться так, что ваша ссылка не установлена ​​до остановки компонента.

На основе вашего образца вы можете достичь своей цели следующим образом:

public class B {

    private boolean started;

    private AtomicReference<A> a = new AtomicReference<A>();

    @Reference(name = "a", 
        service = A.class,  
        optional = false,
        multiple = false,
        dynamic = true,
        unbind = "unsetA")
    public void setA(A a) {
        this.a.set(a) = a;
    }

    public void unsetA(A a) {
        this.a.set(null);
        if (!started) {
            componentIsStoppedAndReferencesAreUnset();
        }
    }

    @Activate
    public void activate() {
        started = true;
    }

    @Deactivate
    public void deactivate() {
        started = false;
        if (this.a.get() == null) {
            componentIsStoppedAndReferencesAreUnset();
        }
    }

    public void componentIsStoppedAndReferencesAreUnset() {
        // Implement your logic here
    }
}

Если у вас было больше ссылок, вы должны проверить их все на null во всех неустановленных методах и в методе деактивации. Если бы у вас также была статическая ссылка, вы могли бы пропустить проверку в методе деактивации, так как она была бы уверена, что статическая ссылка не будет установлена ​​после метода деактивации.

Обратите внимание, что если вы используете динамическую ссылку, вы должны использовать AtomicReference в качестве переменной-члена для безопасности потоков.

person Balazs Zsoldos    schedule 22.09.2014