我是 OSGi 的新手,我有兴趣将我的一些 jar 改造为 OSGi 包。 但是,我不想向任何特定于 osgi 的库引入额外的依赖项。
因为这样的注解是不可能的,编程调用捆绑上下文等等也是不可能的。
我发现声明式服务与我的要求接近匹配,它允许我在不影响依赖项的情况下公开我的较低级别的包,但是在较高级别(我实际上需要使用服务的地方)我仍然有点卡住了。
我知道组件 xml 可用于声明服务的实现(我已经将其用于我的较低级别的 jar),还可以将服务实例注入(inject)特定的 POJO。
现在我的问题是:如何访问注入(inject)了服务的 osgi 管理的 POJO?是否完全有可能不引入新的依赖关系,或者我是否必须以编程方式进行?
如果是后者,有人可以指出一些代码的方向来执行此操作,换句话说,bundleContext.getServiceReference() 的组件等价物?
更新
澄清一下,如果您学习了本教程的第五部分:http://www.vogella.com/articles/OSGiServices/article.html
他声明了一个 component.xml 文件,该文件使用引用绑定(bind)将服务注入(inject)对象 QuoteConsumer。 太好了,现在我如何获得一个注入(inject)了必要服务的 QuoteConsumer 实例,我不能很好地执行“new QuoteConsumer()”,对吗?
更新 2
目前我正在将 osgi 创建的实例注册为可以请求的静态变量,我认为这不是最好的方法,尤其是因为我无法将构造函数设置为私有(private)。 (后者至少会导致真正的单例)
基本上工厂类有:
private void activate() {
instance = this;
}
更新 3
工厂的完整示例:
public class Factory {
private static Factory instance;
public static Factory getInstance() {
if (instance == null)
instance = new Factory();
return instance;
}
private MyInterface implementation;
public void setMyInterface(MyInterface implementation) {
this.implementation = implementation;
}
public void unsetMyInterface(MyInterface implementation) {
implementation = null;
}
public MyInterface getMyInterface() {
if (implementation == null) {
ServiceLoader<MyInterface> serviceLoader = ServiceLoader.load(MyInterface.class);
Iterator<MyInterface> iterator = serviceLoader.iterator();
if (iterator.hasNext())
implementation = iterator.next();
else
implementation = new MyInterfaceStub();
}
return implementation;
}
@SuppressWarnings("unused")
private void activate() {
instance = this;
}
@SuppressWarnings("unused")
private void deactivate() {
instance = null;
}
}
然后任何客户端代码都可以:
Factory.getInstance().getMyInterface();
并接收 OSGi 加载服务、SPI 加载一个或一个 stub 。 如有必要,您仍然可以手动设置服务实例。
UPDATE4
进一步澄清:此模式并不适用于从头开始设计为在 OSGi 容器中运行的应用程序,而是适用于必须在任何地方运行的低级库,即使在 OSGi 容器上也不能假设所有消费者实际上都在使用 OSGi。
最佳答案
你听起来很困惑……:-)服务是静态工厂的替代品,所以你的工厂不应该存在。
DS 的整体理念是,对于每个组件:
- 等待直到满足其依赖性
- 创建实例
- 将实例绑定(bind)到它的依赖
- 在实例上调用激活
- 将实例注册为服务
因此,无论何时您获得由 DS 管理的服务,它都已经注入(inject)(绑定(bind))了它的依赖项。因此,只要您保持服务依赖性,就永远不需要静态工厂……服务的整个理念是您没有静态工厂,只能使用(注入(inject)的)实例。 OSGi 最好的部分之一是您很少与工厂打交道。
关于不使用注释的要求的评论。 OSGi 注释只是类时间,它们不会创建运行时依赖性。我强烈建议使用它们,因为它们使服务像类一样轻量,并且与 XML 相比是类型安全的。
使用注释而不会使代码困惑的一个技巧是创建扩展您希望成为 OSGi 组件的实现类,并在此类上添加注释。
关于java - 使用 OSGi 将组件注入(inject) POJO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16855938/