【发布时间】:2015-01-02 02:23:33
【问题描述】:
我有一个项目正在使 OSGi 兼容。该代码依赖于 Java SPI 来添加实现(META-INF/服务)。我不想在 OSGi 环境中使用 SPI(例如通过使用 SPI Fly),我宁愿使用 OSGi 方式。但是,我想保持对非 OSGi 环境的 SPI 支持。我的方法如下:
工厂看起来像这样(使用 BND 注释):
@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 注释(或者更确切地说是从它生成的声明性服务)填充 MyFactory。
如果 MyDiscoverable 的实现需要其他类似于 MyFactory 的工厂,我在 MyFactory.newInstance() 中放了这样的东西:
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 不兼容。这种限制在大多数情况下是可以控制的,但作为一般解决方案是不可接受的。
有没有更好的方法?如果有,怎么做?
【问题讨论】:
标签: java design-patterns osgi