Как получить службу osgi по идентификатору с помощью Spring?

Весенний нуб здесь.

У меня есть служба osgi, определенная следующим образом в одном из моих пакетов:

<osgi:service id="myModelInterpreter" ref="myModelInterpreterService" interface="*.IModelInterpreter" />

Я знаю, что могу получить к нему доступ из другого пакета через BundleContext выполняет getServiceReference (передавая IModelInterpreter.class.getName), а затем getService.

Есть ли способ получить услугу через идентификатор (myModelInterpreter) вместо использования интерфейса (передается как IModelInterpreter.class.getName в getServiceReference)?

Любая помощь приветствуется.


person JohnIdol    schedule 12.10.2012    source источник
comment
Каковы ваши доводы в пользу попытки создать экземпляр bean самостоятельно.   -  person dardo    schedule 12.10.2012
comment
создать экземпляр объекта, вы имеете в виду, что это будет экземпляр Spring Bean? Управляется ли класс (его имя как String para) Spring?   -  person Kent    schedule 12.10.2012
comment
@Kent да, класс управляется spring, его нет в моем пути сборки, поскольку он представлен как обнаруживаемая служба osgi, поэтому я не могу использовать отражение   -  person JohnIdol    schedule 12.10.2012
comment
Не уверен, что это сработает, но, возможно, вы можете попробовать выполнить Class.forName(String className) и использовать результат этого вызова для вызова AutowireCapableBeanFactory.createBean.   -  person mthmulders    schedule 12.10.2012
comment
Переименованный для включения osgi, насколько я понимаю в настоящее время, вы должны иметь возможность включать управляемый компонент osgi в контейнер spring во время выполнения.   -  person dardo    schedule 12.10.2012
comment
Что вы собираетесь делать с bean-компонентом в своем коде, если у вас нет доступа во время компиляции? У вас есть доступный интерфейс?   -  person artbristol    schedule 12.10.2012
comment
@artbristol У меня точно есть интерфейс :)   -  person JohnIdol    schedule 12.10.2012
comment
@JohnIdol Тогда используйте getBean с классом интерфейса. Однако, если вы впервые используете Spring и OSGi, я рекомендую вам ознакомиться с Gemini Blueprint eclipse.org/ Близнецы/схема   -  person artbristol    schedule 12.10.2012
comment
все - я только что отредактировал свой вопрос, надеюсь, теперь он имеет больше смысла   -  person JohnIdol    schedule 12.10.2012
comment
Это объявление сделано с использованием Spring DM?   -  person Robin    schedule 12.10.2012
comment
@ Робин, да, это в файле osgi-config.xml для пакета, который предоставляет службу osgi.   -  person JohnIdol    schedule 12.10.2012
comment
Мне любопытно, почему вы приняли ответ, в котором используется декларативный подход, когда вы прокомментировали мой ответ, что вы не можете использовать декларативный подход.   -  person Robin    schedule 15.10.2012
comment
Ответ @Robin Christian дает мне способ (фильтры, пример которых включен) для идентификации службы osgi за пределами интерфейса. Я не буду использовать объявление ссылки для потребителя службы, я буду использовать API для применения фильтра к интерфейсу + мое пользовательское свойство id, которое позволяет мне динамически выбирать правильную службу на основе внешней конфигурации.   -  person JohnIdol    schedule 15.10.2012
comment
@ Робин, я вижу, вы предложили то же самое, что и ответ Кристиана в комментарии. Принимая во внимание ваш комментарий, с моей точки зрения, 2 ответа эквивалентны. Что действительно помогло бы, так это пример того, как программно получить доступ к сервису, используя интерфейс и пользовательское свойство в качестве фильтра (или даже ссылку на пример, похоже, не очень много), но я думаю, это другой вопрос :)   -  person JohnIdol    schedule 15.10.2012


Ответы (3)


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

Как это:

<service ref="myModelInterpreterService" interface="*.IModelInterpreter">
  <service-properties>
    <beans:entry key="myId" value="myModelInterpreter"/>
  </service-properties>
</service>

Затем в другом комплекте вы можете фильтровать свойства:

<reference id="myModelInterpreterService" interface="com.xyz.IModelInterpreter"
  filter="(myId=myModelInterpreter)"/>
person Christian Schneider    schedule 13.10.2012
comment
Это звучит очень близко к тому, что мне нужно - спасибо. Я попробую. Любые примеры этой фильтрации по свойству? Кроме того, просто чтобы развеять некоторые сомнения, которые у меня есть, не должен ли я захватить службу по идентификатору, как и любой другой компонент в контексте весны? r отличается ли он тем, что это сервис (следовательно, не bean-компонент)? - person JohnIdol; 15.10.2012
comment
Мой ответ выше содержит фильтр для свойства myId (my=myModelInterpreter). Вы можете использовать подобные фильтры для любого свойства, которое вы определяете с помощью службы. Сервис сильно отличается от боба. Бин является внутренней конструкцией Spring и не имеет значения вне контекста Spring. Служба указана в спецификации OSGi. Spring позволяет определять службы OSGi, но не все метаданные компонента публикуются. Вероятно, свойства, которые вы определяете явно, — это все, что вы можете увидеть в другом пакете. - person Christian Schneider; 15.10.2012
comment
Теперь ясно: Spring позволяет определять службы OSGi, но не все метаданные компонента публикуются. - большое спасибо за твою помощь. - person JohnIdol; 15.10.2012
comment
На самом деле вы можете использовать идентификатор, Spring DM опубликует идентификатор компонента как свойство службы. Вот почему ссылочный тег файла конфигурации DM имеет необязательный атрибут bean-name, который затем будет автоматически фильтровать это свойство. Вы можете получить полное имя свойства через консоль после публикации службы, если вы ищете вне DM. - person Robin; 15.10.2012
comment
@Robin интересно - вы говорите, что идентификатор не будет тем же идентификатором, который я объявляю в пакете услуг? И есть ли способ программно получить службу по идентификатору, как и любой другой компонент из контекста Spring? - person JohnIdol; 15.10.2012

Поскольку вы уже используете Spring DM для объявления своего сервиса, самый простой способ использовать его — сделать то же самое с другой конфигурацией dm.

<osgi:reference id="modelInterpreter" interface="IModelInterpreter" />

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

<osgi:reference id="modelInterpreter" bean-name="myModelInterpreter" interface="IModelInterpreter" />

Затем вы просто используете bean-компонент «modelInterpreter» в своей обычной конфигурации Spring в потребительском комплекте. Эту же строку можно выполнить и с использованием bean-name, но я почти уверен, что для этого все равно потребуется атрибут interface или interfaces, поскольку они единственный приемлемый способ поиска OSGi-сервисов.Использование bean-name просто приукрашивает использование фильтра свойств при поиске сервисов, который в большинстве случаев вам не нужен, поскольку на самом деле он создает более тесную зависимость между пакетами. проще, например, издеваться над вашей зависимостью без такой тесной связи.

Если, с другой стороны, вы хотите получить доступ к сервису без использования DM, то я бы порекомендовал вам использовать прямой путь OSGi, используя либо прямой доступ (через код) к реестру, либо внедрить его с помощью DS (Declarative Services). ).

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

person Robin    schedule 12.10.2012
comment
Спасибо за Ваш ответ. Моя проблема в том, что мне нужно найти службу на основе вечного значения конфигурации (идентификатора), поэтому я не могу декларативно указать свою ссылку на данную службу. В основном мне нужно прочитать кучу идентификаторов сервисов из файла конфигурации и получить все сервисы, соответствующие этим идентификаторам, запустить их и вызвать общие методы. Я не знаю, сколько их - например, у меня есть более одного сервиса, который реализует IModelInterpreter, поэтому мне нужно искать их по какому-то идентификатору (я выбрал идентификатор определения службы). - person JohnIdol; 12.10.2012
comment
Вы можете сделать это, используя идентификаторы в качестве свойств при регистрации службы и фильтруя это свойство при поиске ссылки на службу. Spring DM уже помещает идентификатор компонента в качестве такого свойства. Однако я бы объявил свойство более явно. Вам все равно понадобится интерфейс для поиска, я не думаю, что есть какой-то способ обойти это. - person Robin; 15.10.2012

Или просто используйте

Object obj = beanFactory.createBean(YourClass.class);
person Adrian Adamczyk    schedule 12.10.2012