首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >结合使用OSGi和Java SPI

结合使用OSGi和Java SPI
EN

Stack Overflow用户
提问于 2014-11-06 02:56:30
回答 2查看 500关注 0票数 1

我有一个项目,我正在使OSGi兼容的过程中。代码依赖于Java SPI来添加实现(META-INF/services)。我不想在OSGi环境中使用SPI (例如,通过使用SPI Fly),我更喜欢使用OSGi方式。但是,我希望保留对非OSGi环境的SPI支持。我的方法如下:

工厂看起来像这样(使用BND注释):

代码语言:javascript
复制
@Component
class MyFactory implements MyFactoryService {

    public MyFactory() {
         ...
    }

    //This method is reserved for non-OSGi use (uses SPI to find implementations)
    public static MyFactory newInstance() {
        MyFactory ret = new MyFactory();
        Iterator<MyDiscoverable> i = ServiceLoader.load(MyDiscoverable.class).iterator();
        while (i.hasNext()) {
            ret.addFactory(i.next());
        }
    }

    @Reference
    public void addFactory(MyDiscoverable f) {
        ...
    }

}

在OSGi上下文中,MyFactory位于OSGi私有包中,必须使用MyFactoryService接口通过服务注册中心进行检索。然后,OSGi框架使用@Reference注释(或者更确切地说,是从它生成的声明性服务)填充引用。

如果MyDiscoverable的实现需要类似于MyFactory的其他工厂,我在MyFactory.newInstance()中放入如下内容:

代码语言:javascript
复制
 public static MyFactory newInstance() {
        MyFactory ret = new MyFactory();
        MyOtherFactory other = MyOtherFactory.newInstance();
        Iterator<MyDiscoverable> i = ServiceLoader.load(MyDiscoverable.class).iterator();
        while (i.hasNext()) {
            MyDiscoverable x = i.next();
            //This method is also annotated with @Reference in the implementation, to support OSGi use
            x.setReference(other);
            ret.addFactory(x);
        }
}

这在OSGi和SPI上下文中都可以很好地工作。我对此的一个问题是,工厂必须知道每个实现可能需要哪些其他工厂(并提供它们)。这是因为我还没有找到一种方法,让实现创建自己的工厂实例,而不使其与OSGi不兼容。这个限制在很大程度上是可以管理的,但作为一般的解决方案是不可接受的。

有没有更好的方法?如果是这样的话,是怎么做的?

EN

回答 2

Stack Overflow用户

发布于 2014-11-08 02:00:31

一种方法是显式地向MyDiscoverable提供它是通过newInstance创建的信息,例如x.populateWithSPI()。这样,实现本身就可以用MyOtherFactory.newInstance()调用setReference。

票数 0
EN

Stack Overflow用户

发布于 2018-07-23 22:42:52

OSGI使用IOC容器,并且像所有IOC容器(Guice、Spring等)一样,IOC容器必须负责类的实例化。

SPI支持在运行时发现实现,并且SPI将这些实现实例化为发现的一部分。

您无法将同一个类用于SPI和OSGI (或任何其他IOC容器),因为它们有不同的实例化类的方法。我建议将这两种方法分开。

您可以围绕SPI使用的MyFactoryService创建一个包装类。这个类可以被称为MyFactoryServiceProvider,它可以返回一个类引用供MyFactoryService实例化,然后将MyDiscoverable的引用传递给它。

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

https://stackoverflow.com/questions/26764903

复制
相关文章

相似问题

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