首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Guice/Peaberry用于osgi声明性服务

将Guice/Peaberry用于osgi声明性服务
EN

Stack Overflow用户
提问于 2015-02-12 08:27:30
回答 1查看 441关注 0票数 2

我想解决以下问题,并需要建议,什么是最好的解决方案。

我有一个包A,其中定义了一个服务接口X。包B提供X的服务实现,并将实现贡献给工具。A和B使用Google和Peaberry来配置对象的设置。

我可以使用两种可能性来贡献服务实现:

  1. 使用eclipse扩展:在这个解决方案中,我可以使用Peaberry的GuiceExtensionFactory机制来使用Guice创建服务实现,因此可以注入实现所需的内容。这里的缺点是,在定义扩展点的包中,我需要样板代码来解析扩展,因为据我所知,无法将扩展注入到使用扩展的类中。这个看起来是这样的:

代码语言:javascript
复制
<extension point="A.service.X">
  <xservice
    ...
    class="org.ops4j.peaberry.eclipse.GuiceExtensionFactory:B.XImpl"
    .../>
</extension>
<extension
  point="org.ops4j.peaberry.eclipse.modules">
  <module
    class="B.XModule">
  </module>
</extension>

但我需要这样的样板代码:

代码语言:javascript
复制
private List<X> getRegisteredX() {
    final List<X> ximpls = new ArrayList<>();
    for (final IConfigurationElement e : Platform.getExtensionRegistry().getConfigurationElementsFor(               X_EXTENSION_POINT_ID)) {
        try {
            final Object object = e.createExecutableExtension("class"); //$NON-NLS-1$
            if (object instanceof X) {
                ximpls.add((X) object);
            }
        } catch (final CoreException ex) {
            // Log
        }
    }
    return ximpls;
}
  1. 使用OSGI服务:我这里的主要问题是确保注册了该服务。我希望延迟加载包,因此至少需要访问包的一个类。使用Peaberry以编程方式注册服务有一个问题,因为从来没有人请求包的类。解决方案是将服务作为声明性服务提供,但我不知道以某种方式创建服务实现的方法,即我可以使用Guice注入所需的对象。

所以我有一些问题:

  1. 到目前为止,我还不知道有什么东西实现了在扩展点读取扩展并允许使用扩展将扩展注入类所需的代码吗?
  2. 是否有一种方法可以确保服务被提供,即使它是使用标准Peaberry机制添加的,即在请求服务时激活包?
  3. 是否有类似于声明性服务的GuiceExtensionFactory的方法,以便服务实现的创建可以由包的注入器完成?看上去像:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="Ximpl">
   <implementation class="some.generic.guiceaware.ServiceFactory:B.Ximpl"/>
   <service>
      <provide interface="A.X"/>
   </service>
</scr:component>

总之,我想要一个由Guice生成的服务实现,并且我希望将服务实现简单地注入到使用服务的类中,而不需要大量的样板代码。有谁能解决这个问题吗?

对不起,我想问一下,但是我在网上搜索了很长一段时间,到目前为止我还没有找到解决办法。

谢谢并致以良好的问候,拉尔斯

EN

回答 1

Stack Overflow用户

发布于 2015-02-19 14:39:08

我找到了一个解决方案,但由于我没有找到它,没有经过大量的尝试和思考,我认为我在这里分享它。根据我在帖子中提到的选项,我的解决方案使用了第一个选项,即Eclipse扩展点和扩展。为了在扩展点的上下文中使用Guice,有两个方面需要考虑:

提供由Guice注入器创建的扩展

这里很好地解释了这一点:https://code.google.com/p/peaberry/wiki/GuiceExtensionFactory。我有一句话要说。扩展对象的创建是在GuiceExtensionFactory内部的注入器中完成的,因此它是自己的上下文,需要由作为工厂附加扩展的模块配置。如果您有其他需要,需要自己在包中创建注入器,这可能会成为一个问题。

定义一个扩展点,以便简单地将扩展注入到使用扩展的类中。

首先要做的是像往常一样定义扩展点模式文件。它应该包含必须由扩展实现的接口的引用。

扩展点的id必须连接到由扩展提供的接口,接口由guice/peaberry注入。因此,peaberry提供了一个注释,用于对接口进行注释:

代码语言:javascript
复制
import org.ops4j.peaberry.eclipse.ExtensionBean;

@ExtensionBean("injected.extension.point.id")
public interface InjectedInterface {
...
}

在某些网页上,您还可以找到这样的信息:如果id等于接口的限定名,则可以在没有注释的情况下直接找到它,但我没有尝试。

为了启用注入,您必须做两件事来配置Guice注入器创建。

首先,必须将Peaberry的EclipseRegistry对象设置为ServiceRegistry。其次,必须完成扩展实现到提供的服务的绑定。

注入器的创建必须以这样的方式进行:

代码语言:javascript
复制
import org.osgi.framework.BundleContext;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.ops4j.peaberry.eclipse.EclipseRegistry;

import static org.ops4j.peaberry.Peaberry.*;

void initializer() {
    Injector injector = Guice.createInjector(osgiModule(context, EclipseRegistry.eclipseRegistry()), new Module() {
               binder.bind(iterable(InjectedInterface.class)).toProvider(service(InjectedInterface.class).multiple());
        });
}

这样就可以简单地注入扩展实现:

代码语言:javascript
复制
private Iterable<InjectedInterface> registeredExtensions;

@Inject
void setSolvers(final Iterable<InjectedInterface> extensions) {
    registeredExtensions = extensions;
}

按照所描述的方式,可以通过使用Guice的类实现注入扩展,以获得依赖项。

到目前为止,我还没有找到使用osgi服务的解决方案,但是也许有人有想法。

向你问好,拉尔斯

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28472618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档