Лучшая практика слабой связи OSGi - PullRequest
5 голосов
/ 09 февраля 2011

Я хотел бы знать, что считается лучшими практиками или шаблонами для отделения кода приложения от кода платформы, особенно в отношении OSGi.

Я собираюсь использовать пример из Felix SCRстраницы

Примером службы является Comparator

package sample.service;
import java.util.Comparator;
public class SampleComparator implements Comparator
{
    public int compare( Object o1, Object o2 )
    {
        return o1.equals( o2 ) ? 0 : -1;
    }
}

Приведенный выше код не содержит рамок, он сфокусирован и лаконичен.Чтобы сделать это доступным для приложения при использовании OSGi, необходимо зарегистрировать его в реестре сервисов.Один из способов, как описано на связанных страницах Феликса, заключается в использовании среды выполнения компонентов службы.

// OSGI-INF/sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<component name="sample.component" immediate="true">
  <implementation class="sample.service.SampleComparator" />
  <property name="service.description" value="Sample Comparator Service" />
  <property name="service.vendor" value="Apache Software Foundation" />
  <service>
    <provide interface="java.util.Comparator" />
  </service>
</component>

и

Service-Component: OSGI-INF/sample.xml

Все хорошо, моя реализация службы не имеет связи ввсе в OSGI.

Теперь я хочу использовать службу ...

package sample.consumer;
import java.util.Comparator;
public class Consumer {
    public void doCompare(Object o1, Object o2) {
        Comparator c = ...;
    }
}

Используя стратегию поиска SCR, мне нужно добавить методы только для фреймворка:

protected void activate(ComponentContext context) {
    Comparator c = ( Comparator ) context.locateService( "sample.component" );
}

Используя стратегию событий SCR, мне также нужно добавить методы только для фреймворка:

protected void bindComparator(Comparator c) {
    this.c = c;
}

protected void unbindComparator(Comparator c) {
    this.c = null;
}

Ни один из них не очень обременителен, хотя я думаю, что вы, вероятно, в конечном итоге получите достаточное количество кода этого типа, дублированного вклассы, что делает фильтрацию более шумной.

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

package sample.internal;
public class OsgiDependencyInjector {
    private Consumer consumer;
    protected void bindComparator(Comparator c) {
        this.consumer.setComparator(c);
    }

    protected void unbindComparator(Comparator c) {
        this.consumer.setComparator(null);
    }
}

Хотя я не уверен, как вы это устроите в конфигурации SCR.

Также есть org.apache.felix.scr.annotations, хотя это означает, что все будет работать только в том случае, еслиты строишь с мейвомн-Scr-плагин.Не так уж плохо на самом деле, и, AFAICT, они не налагают последствий во время выполнения.

Итак, теперь, когда вы все это прочитали, что, по вашему мнению, является лучшим способом использования предоставляемых OSGi сервисов без «загрязнения» кода приложения кодом платформы?

Ответы [ 3 ]

3 голосов
/ 16 февраля 2011

1) Я не думаю, что методы связывания загрязняют ваш код, они просто устанавливают компоненты (вы можете также назвать их setXXX, чтобы быть более традиционными). Они вам понадобятся и для юнит-тестирования.

2) Если вы используете bnd (то есть в maven, ant, bndtools, плагине eclipse и т. Д.), То вы также можете использовать аннотации bnd. Затем bnd автоматически создаст (всегда ужасный) xml для вас.

package sample.service;
import java.util.Comparator;
import aQute.bnd.annotations.component.*;

@Component
public class SampleComparator implements Comparator {
    public int compare( Object o1, Object o2 ) {
        return o1.equals( o2 ) ? 0 : -1;
    }
}

@Component
class Consumer {
    Comparator comparator;

    public void doCompare( Object o1, Object o2 ) {
      if ( comparator.compare(o1,o2) ) 
        ....
    }

    @Reference
    protected setComparator( Comparator c ) {
       comparator = c;
    }
}

В своем манифесте просто добавьте:

Service-Component: *

Это будет забрано bnd. Так что нет кода OSGi в коде вашего домена. Вы можете быть озадачены отсутствующим методом, но по умолчанию для bnd используется статическая привязка. Таким образом, метод set вызывается до того, как вы его активируете, и вы деактивируете, прежде чем будет вызван unset. До тех пор, пока ваш потребительский объект будет также µ-сервисом, вы в безопасности. Посмотрите bndtools , домашнюю страницу bnd и мои блоги для получения дополнительной информации о µservices.

PS. Ваш пример является недействительным кодом, потому что o1 будет отвечать как больше, так и меньше, чем o2, если o1! = O2, это не разрешено контрактом Comparator и сделает сортировку нестабильной.

2 голосов
/ 09 февраля 2011

Я напишу вам, как мы это делаем в моем проекте.В качестве контейнера OSGi мы используем Fuse ESB, хотя где-то внутри Apache Karaf можно найти.Чтобы не загрязнять наш код, мы используем Spring DM (http://www.springsource.org/osgi),, что значительно облегчает взаимодействие с контейнером OSGi. Он протестирован "на Equinox 3.2.x, Felix 1.0.3+ и Knopflerfish 2.1.x как часть нашего непрерывного процесса интеграции"(новейшая версия).

Преимущества этого подхода:

  • все настройки" osgi "в файлах XML - код не загрязнен
  • возможность работать с различнымиреализации контейнера OSGi

Как это выглядит?

  • служба публикации в реестре OSGi:

  • импорт службы из реестра OSGi:

Более того, для создания действительного OSGiсвязки мы используем maven-bundle-plugin.

1 голос
/ 07 апреля 2011

Преимущество аннотаций felix по сравнению с аннотациями в aQute.bnd.annotations.component заключается в том, что методы bind и unbind автоматически создаются плагином felix scr (вы можете аннотировать личное поле). Недостаток плагина felix заключается в том, что он работает с исходными кодами Java и поэтому не работает с файлами классов, созданными на других языках (например, scala).

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