java - 使用 OSGi 将组件注入(inject) POJO

标签 java osgi

我是 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 的整体理念是,对于每个组件:

  1. 等待直到满足其依赖性
  2. 创建实例
  3. 将实例绑定(bind)到它的依赖
  4. 在实例上调用激活
  5. 将实例注册为服务

因此,无论何时您获得由 DS 管理的服务,它都已经注入(inject)(绑定(bind))了它的依赖项。因此,只要您保持服务依赖性,就永远不需要静态工厂……服务的整个理念是您没有静态工厂,只能使用(注入(inject)的)实例。 OSGi 最好的部分之一是您很少与工厂打交道。

关于不使用注释的要求的评论。 OSGi 注释只是类时间,它们不会创建运行时依赖性。我强烈建议使用它们,因为它们使服务像类一样轻量,并且与 XML 相比是类型安全的。

使用注释而不会使代码困惑的一个技巧是创建扩展您希望成为 OSGi 组件的实现类,并在此类上添加注释。

关于java - 使用 OSGi 将组件注入(inject) POJO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16855938/

相关文章:

java - 日志记录的通用方法

java - OSGI API 包中的具体类

java - 无法启动 OSGi 包,缺少 com.ibm.uvm.tools

grails - Karaf 4上的Grails3。有人设法做到了吗?

java - KARAF OSGI bundle 上的自定义 hibernate.cfg.xml 位置

osgi - 影响最小的 OSGi 容器

java - 是什么导致 Java 7 中的 G1 垃圾收集器中止其并发标记阶段?

java - 从 Android 网站解析

java - 如何将加速器数据减少到两位小数?

java - 在纵向和横向之间翻转时随机生成的单词会发生变化