Как обрабатывать различные @Reference в OSGi DS Component - PullRequest
0 голосов
/ 25 февраля 2020

У меня проблема со следующей ситуацией: Сервер ожидает одну или несколько функций. Когда функция связана, вызывается функция bindFunction. Он должен вызывать doSomething () любой SpecificSystem.

Когда в моем контейнере OSGi нет SpecificSystem, ничего не происходит, что хорошо, потому что ссылка на систему не выполняется. Проблема возникает, когда я добавляю SpecificSystem в свой контейнер. В этом случае bindFunction вызывается до того, как ссылка на систему установлена, что приводит к исключению NullPointerException внутри bindFunction.

Существует ли какой-либо OSGi-способ убедиться, что ссылка на систему установлена ​​при выполнении функции bindFunction, чтобы я мог безопасно вызвать system.doSomething ( ) внутри функции bindFunction?

Ответы [ 3 ]

1 голос
/ 25 февраля 2020

Вы идете по опасной воде здесь :-) Вам требуется заказ . Ваш код предполагает, что ссылка bindFunction вызывается после ссылки system.

Спецификация OSGi гарантирует, что инъекция происходит в лексическом порядке ссылочного имени. (Конечно, это верно только для доступных услуг.)

Дешевый способ - назвать ваши ссылки так, чтобы имя ссылки system было лексически ниже, чем имя bindFunction ссылка, например asystem или _system. Инъекция происходит в лексическом порядке.

Это ужасно, если конечно. Способ справиться с этим - просто внедрить сервисы Function и использовать их при необходимости вместо того, чтобы активно что-то делать в вашей функции bind Это делает вещи более ленивыми, что почти всегда хорошо.

0 голосов
/ 26 февраля 2020
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;

@Component(name = "ServerComponent", immediate = false)
public class Server {

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    System system;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected void bindFunction(Function func) {

    }

    @Activate
    public void activate() {

    }   
}

Вы можете вызвать doSomething () в методе активации. Osgi гарантирует порядок вызова метода с аннотацией @Reference.

При условии, что ссылки на систему и функции получены, метод activ будет вызываться средой OSGi. Вы можете вызвать метод system.doSomething () в методе activ (). Аннотация @Reference (cardinality = ReferenceCardinality.MANDATORY) означает, что вызов метода активации после получения ссылок.

0 голосов
/ 25 февраля 2020

В вашем примере похоже, что ссылка на Систему обязательна. В этом случае ваш серверный компонент будет работать только при наличии системной службы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...