Java OSGI-选择要从另一个组件类激活的捆绑包

Java OSGI-选择要从另一个组件类激活的捆绑包,java,osgi,apache-karaf,apache-felix,Java,Osgi,Apache Karaf,Apache Felix,我想开发OSGI存储服务,所以我创建了一个名为Store的接口。现在,我有两个类实现这个接口 SqlStorage.java @Component(immediate = true) @Service public class SqlStorage implements Store { //some code here } @Component(immediate = true) @Service public class MongoStorage implements Store {

我想开发OSGI存储服务,所以我创建了一个名为
Store
的接口。现在,我有两个类实现这个接口

SqlStorage.java

@Component(immediate = true)
@Service
public class SqlStorage implements Store {
    //some code here
}
@Component(immediate = true)
@Service
public class MongoStorage implements Store {
    //some code here
}
MongoStorage.java

@Component(immediate = true)
@Service
public class SqlStorage implements Store {
    //some code here
}
@Component(immediate = true)
@Service
public class MongoStorage implements Store {
    //some code here
}
现在,我有另一个捆绑包,它依赖于
存储

@Component(immediate = true)
@Service
public class StoreManager implements StoreService {
    // how can I select one of the implmentation here
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    public Store store;
}
StoreManager
如何选择要使用的
Store
实现

假设,
StoreManager
能够选择使用SQL还是MongoDB作为存储


这种方案可行吗?

您的门店经理希望如何决定使用哪种门店实现?正如您目前所定义的,存储实现是等效的,同样好的答案,因此OSGi将任意选择一个

如果这不是您想要的,那么您需要添加服务属性来区分存储。例如:

@Component(property = { "region=NorthAmerica", "language=en_US" })
@Component(property = { "region=Europe", "language=en_GB" })
@Component(property = { "region=Asia", "language=jp" })
然后,您的门店经理可以使用目标过滤器选择它想要的门店。例如,如果它想要一个英语商店(但不关心美式英语和英式英语),那么它可以使用以下过滤器:

@Reference(target = "(language=en*)")

这正是我想要的。我希望
StoreManager
能够选择
Store
。现在,这个键值属性可以重新定义吗?我想使用适当的名称,而不是像您的示例中那样使用
区域
语言
。此外,我想知道是否可以通过CLI或GUI动态实现这种场景。您可以使用您喜欢的任何名称,而不是在
@组件
@参考
中硬编码。“region”和“language”只是我凭空捏造的例子。如果您希望对目标服务选择进行编程控制而不是声明控制,那么您需要使用具有多个基数的引用来获得所有服务的可见性。然后,您可以查看服务的属性,并根据自己的喜好对其进行选择。