在OSGi应用程序中,我有一个类层次结构如下:
public interface IA {
public void someMethod();
}
public abstract class AbstractA implements IA {
public void someMethod(SomeObject s) {
System.out.println(this.getClass());
}
}
public class ImplAA extends AbstractA {
//Some other methods
}
public class ImplAB extends AbstractA {
//Some other methods
}
接口,抽象类和实现有4种不同的包。 另一个包包含一个类似这样的类:
public class SomeClass {
private IA implAAInstance;
private IA implABInstance;
protected void bindToAA(IA ia) {
implAAInstance = ia;
}
protected void bindToAB(IA ia) {
implABInstance = ia;
}
protected void sendStuff(SomeObject p, SomeObject q) {
implAAInstance.someMethod(p);
implABInstance.someMethod(q);
}
}
方法bindToAA
和bindToAB
是绑定函数,分别绑定到包含类ImplAA
和ImplAB
的包。
在XML组件定义中,它如下所示:
<reference bind="bindToAA" cardinality="0..1" interface="path.to.IA" name="ImplAA" policy="dynamic"/>
<reference bind="bindToAB" cardinality="0..1" interface="path.to.IA" name="ImplAB" policy="dynamic"/>
在包含ImplAA
和ImplAB
的捆绑包中,XML组件定义中有以下重要内容:
<implementation class="path.to.ImplAA"/>
<service>
<provide interface="path.to.IA"/>
</service>
和
<implementation class="path.to.ImplAB"/>
<service>
<provide interface="path.to.IA"/>
</service>
现在的问题是,当我运行代码时,会打印两次ImplAA
。
这是什么原因?我怎样才能打印出正确的实现类?
答案 0 :(得分:3)
好吧,你绑定到IA ...并且有两个IA服务(ImplAA和ImplAB)。那么,为什么DS在使用bindToAA的不同服务实例时会使用与bindToAB不同的服务实例?您只声明需要IA?
两个绑定方法都需要0或1个IA实例,因此这两个服务中的任何一个都与账单匹配,在这种情况下,最好只取一个,因为requirer(SomeClass)似乎并不关心差异。
我头脑中没有一个大问题,为什么你想依赖实例呢? OSGi的全部目的是将实例隐藏起来。如果你有一个依赖要求,那么表达一下,这就是OSGi方式。
否如果您只想打印服务,请将基数设为MULTIPLE并将服务放入列表中。在这种情况下,您表达了对所有IA服务的兴趣。
答案 1 :(得分:1)
您所做的错误是未在xml文件中指定目标。
解决方案是向类AA添加一个属性,其名称类型和值为“aaa”,并调整xml文件中的绑定引用,如下所示:
<reference bind="bindToAA" target="(type=aaa)" cardinality="0..1" interface="path.to.IA" name="ImplAA" policy="dynamic"/>
对于其他服务执行相同的操作,这样当您尝试使用相同的接口绑定一组服务的特定服务时,它可以使用LDAP过滤器使用目标/属性来区分它们。
有关LDAP过滤器的更多信息: Info on LDAP filters