OSGi: преобразование службы в декларативную службу

я связываюсь с OSGi, и прямо сейчас я немного смущен. Я использую гибридную модель обслуживания, означающую смесь декларативных услуг и API низкого уровня.

Рассмотрим следующее объявление части, размещенное в OSGi-INF/component.xml:

<property name="canHandle" type="String" value="Some kind of stuff"/>
<service>
  <provide interface="foo"/>
</service>

и еще один

<property name="canHandle" type="String" value="Some other Stuff"/>
<service>
  <provide interface="foo"/>
</service>

В другом комплекте у меня есть что-то вроде этого:

bar.createSomething(String type){

ServiceReference[] services FrameworkUtil.getBundle(getClass()).getBundleContext()
                .getAllServiceReferences("foo");
for (ServiceReference s : services) {
    if (type.equals(s.getProperty("canHandle")){
        Foo foo = (Foo)FrameworkUtilgetBundle(getClass()).getBundleContext().getService(s);
foo.execute();

Короче говоря, у меня есть интерфейс службы с несколькими реализациями, и во время выполнения я использую тот, который сопоставляет строку со свойствами. Итак, как я могу справиться с этой ситуацией ТОЛЬКО с помощью декларативных сервисов?

Мы используем Virgo, поэтому, если это возможно с помощью весны, это тоже будет вариант.


person hueck    schedule 14.01.2013    source источник
comment
Я всегда удивляюсь, почему люди выбирают DS, а не OSGi Blueprint. Что послужило причиной в вашем случае? Я нашел Blueprint намного проще в использовании (хотя я не проводил много времени с DS после большого знакомства со Spring Framework и поэтому выбрал Blueprint).   -  person Jacek Laskowski    schedule 14.01.2013
comment
Причина в том, что я новичок во всем, что связано с OSGi, и до сих пор не слышал о Blueprint. Думаю, я попробую   -  person hueck    schedule 15.01.2013
comment
Я никоим образом не эксперт, чтобы сказать, что OSGi Blueprint лучше/хуже, чем DS, но если у вас есть несколько минут свободного времени, дайте статью Разработка приложений OSGi с пакетами Blueprint и WebSphere Application Server V8.5 Liberty Profile попробуйте и отчитайтесь. Это должно помочь вам с легкостью.   -  person Jacek Laskowski    schedule 15.01.2013
comment
DS проще и настоящий OSGi. Blueprint имеет модель, чуждую OSGi, и делает гораздо больше, чем просто обработка сервисов. Худшая часть Blueprint — это затухание динамики и отказ в случае отсутствия зависимостей. И, конечно, XML не в радость... (в DS есть аннотации).   -  person Peter Kriens    schedule 15.01.2013


Ответы (1)


Вы можете сделать это с помощью целевого фильтра для элемента <reference>. Или, используя аннотации bnd:

@Reference(target = "(canHandle=blah)")
public void setFoo(Foo foo) {
    // ...
}

Теперь, даже если доступно несколько экземпляров службы Foo, в ваш компонент будут внедрены только те, которые соответствуют фильтру (canHandle=blah).

Обновить

Было уточнено, что значение, которое должно быть сопоставлено, неизвестно статически. В этом случае статический фильтр использовать нельзя. Но вы все равно можете использовать декларативные сервисы и проверять значение свойства сервиса вручную, например:

@Reference(multiple = true, dynamic = true)
public void setFoo(Foo foo, Map<String,Object> serviceProps) {
    if ("value".equals(serviceProps.get("canHandle"))) {
        // ...
    }
}

Имейте в виду, что теперь вы можете получить несколько совпадающих экземпляров.

person Neil Bartlett    schedule 14.01.2013
comment
Спасибо, но кажется, я что-то упускаю... Во-первых, я не слышал об аннотациях bnd, попробую. А во-вторых, я не знаю тип, так как использовать целевой фильтр? В зависимости от типа я хочу использовать услугу. - person hueck; 14.01.2013
comment
Вам вообще не нужно использовать аннотации. Как сказал Нил, вы можете установить целевой атрибут для элемента «ссылка» в вашем файле component.xml, который затем будет привязываться только к службам, соответствующим фильтру. - person Frank Lee; 14.01.2013
comment
Хорошо, но все же я не понимаю, как динамически применять фильтр. На данный момент в верхнем примере мой фильтр представляет собой параметр строкового типа. Если я укажу целевой атрибут в component.xml, разве это не статика? Может быть, кто-то может привести мне пример или что-то в этом роде? Но все равно спасибо - person hueck; 14.01.2013
comment
Вы не можете изменить фильтр динамически в DS. Если вам нужно это сделать, вам нужно использовать API. Кроме того, не используйте getAllServiceReferences. Все включает службы, которые не совместимы с пространством класса Foo, используемым вашим пакетом. Просто используйте getServiceReferences. И вы можете предоставить строку фильтра в вызове getServiceReferences вместо последующей обработки результатов. - person BJ Hargrave; 14.01.2013
comment
Правильно, я не понимал, что значение фильтра меняется динамически. Я обновил свой ответ. - person Neil Bartlett; 14.01.2013
comment
Значение фильтра также можно установить с помощью администратора конфигурации... это один из самых мощных аспектов DS, который позволяет определить связь между службами в администраторе конфигурации. - person Peter Kriens; 15.01.2013