Dependency injection OSGI依赖注入

Dependency injection OSGI依赖注入,dependency-injection,osgi,bundle,guice,Dependency Injection,Osgi,Bundle,Guice,我已经用依赖框架Guice构建了一个应用程序。现在我将转到OSGI,并开始使用捆绑信息扩展我的JAR 我目前面临的主要问题是,如何正确设置依赖项注入。我有一个包A,它导出了一些包。然后Bundle B定义了一个组件,它需要注入Bundle a的一些对象(类AA) 我可以为bundle a中的类AA设置一个服务,该服务将自动注入,但是如果bundle a也依赖于bundle a中的某个类,该类可能不会导出,该怎么办。我是否必须设置第二个类,然后也作为服务,这将不起作用,因为它没有导出 以下代码将显

我已经用依赖框架Guice构建了一个应用程序。现在我将转到OSGI,并开始使用捆绑信息扩展我的JAR

我目前面临的主要问题是,如何正确设置依赖项注入。我有一个包A,它导出了一些包。然后Bundle B定义了一个组件,它需要注入Bundle a的一些对象(类AA)

我可以为bundle a中的类AA设置一个服务,该服务将自动注入,但是如果bundle a也依赖于bundle a中的某个类,该类可能不会导出,该怎么办。我是否必须设置第二个类,然后也作为服务,这将不起作用,因为它没有导出

以下代码将显示问题:

捆绑

package test.bundleA.api

public class AA {

   @Inject
   public AA(AInternal someReference) {...}
}




package test.bundleA.internal

public class AInternal {...}
B包:

package test.bundleB.api

public class ComponentB {

   @Inject
   public ComponentB(AA refToA) {...}
}
当我将使用导出包中捆绑包A中的任何其他类时,我是否必须为每个类设置一个服务


解决捆绑包内部甚至跨捆绑包边界的依赖注入问题的常用方法是什么?

如果您独立于使用Guice,我建议您使用Eclipse+Bndtools来创建OSGi捆绑包。有了Bndtools,创建OSGi包和通过注释的DI非常容易。让我们举一个例子:

您在bundleA中有一个接口:

public interface Greeting {
   String sayHello(String name);
}
bundleB中的一个实现,
@Component
使我们的捆绑包能够使用OSGi声明性服务

@Component
public class ExampleComponent implements Greeting {
    public String sayHello(String name) {
        return "Hello " + name;
    }
}
最后是第三个bundleC,您希望使用DI并将所有
问候语
实现注入到特定组件中以供使用

@Component
public class GreetingCommand {
    private Greeting greetingSvc;

    @Reference
    public void setGreeting(Greeting greetingSvc) {
        this.greetingSvc = greetingSvc;
    }

    public void greet(String name) {
        System.out.println(greetingSvc.sayHello(name));
    }
}
正如您在
@Reference
中所看到的,您表示希望插入
问候语
接口的实现。上面的示例将OSGi声明性服务与Bndtools结合使用。Bndtools本身接受注释并创建OSGi使用声明性服务所需的XML文件。我不想再深入了。有关更多信息,请参见[1]和[2]。只是想向您展示如何使用声明性服务和Bndtools来创建DI

[1]


[2]

嗯,有一个名为的扩展库,它提供了与OSGi的集成GUI。有一个很好的方法可以将一个服务包注入到另一个包中


希望对您有所帮助。

christian,谢谢您的回答。但是如果我理解正确的话,bndtools只是为声明性服务生成xml,而OSGi框架可以使用它来注册服务。然后我仍然有一个问题,ExampleComponent(我的类AA)在它自己的bundle(内部)中对内部类有依赖性。当ExampleComponent没有无参数构造函数时,OSGi无法创建它。我可以为此使用一个额外的setter,但这是DI setter与构造函数注入的另一个故事/讨论接口描述在另一个包中。通常,您不会将实现与接口放在同一个包中。因此,您只需要依赖于API捆绑包,而使用者具有相同的依赖关系,但从未依赖于实现捆绑包。因此,消费者永远不会直接连接到实现本身,这就是DI想要解决的问题,对吗?!我希望接口描述是在同一个包中还是在另一个包中并不重要。即使该接口位于另一个包中,我们也可以将其称为AInterface,但实现AInterface的ExampleComponent(服务提供者)仍将以某种方式由osgi框架实例化。但ExampleComponent还有一个附加的内部依赖项。框架不能实例化它吗?我错了吗?是的,声明性服务没有从同一个包中注入类的功能。。。除非这些类作为服务发布。但我不明白为什么有人会需要这个。如果类在同一个捆绑包中,那么您可以完全看到它,并可以使用
new
关键字进行实例化。@NeilBartlett但是使用
new
听起来像是违反了DI概念。因为它降低了可测试性的级别。如果某些逻辑发生在ExampleComponent中,而某些逻辑发生在内部,那么使用
new
测试ExampleComponent是相当困难的