我有多个实现相同服务的Impl类。我需要在osgi中编写一个工厂类,在其中我应该编写getter方法以返回适当的Impl对象。下面是我尝试的代码。我被工厂班震惊了。有什么想法可以继续吗?
public interface ServiceA {
public void display();
}
@Component (description = "Test1 service", ds = true, immediate = true)
@Service (value = {ServiceA.class})
class Test1 implements ServiceA{
public void display(){
Log.debug("Test1");
}
}
@Component (description = "Test2 service", ds = true, immediate = true)
@Service (value = {ServiceA.class})
class Test2 implements ServiceA{
public void display(){
Log.debug("Test2");
}
}
//How to write factory ?
class Factory{
public ServiceA getObject(String testType){
if(testType.equals("Test1")){
return Test1;
}
else{
return Test2;
}
}
}
答案 0 :(得分:1)
虽然不清楚您的应用程序打算如何利用这些不同的服务实现,但一种实现方法是使用服务属性,然后在服务使用者处实际引用这些服务时要求该属性,例如:
@Component (description = "Test1 service", ds = true, immediate = true)
@Service (value = {ServiceA.class})
@Property (name = "type", value = "test1")
class Test1 implements ServiceA{
// ...
}
@Component (description = "Test2 service", ds = true, immediate = true)
@Service (value = {ServiceA.class})
@Property (name = "type", value = "test2")
class Test2 implements ServiceA{
// ...
}
...在消费者方面,您只需为参考添加服务选择标准,例如:
@Component (...)
class MyConsumer {
// ...
@Reference(target="(type=test2)")
ServiceA testService2;
// ...
}
无需工厂! :)
有关更多信息,请查看this little article。
如果您需要基于运行时服务请求属性动态路由到特定的服务实现,则还可以保留对所有服务实现的引用,并使用所需的属性进行映射以进行快速选择,例如:
@Component (...)
class MyConsumer {
// ...
private final Map<String, ServiceA> services = // ...
@Reference(
cardinality = ReferenceCardinality.MULTIPLE,
policy = ReferencePolicy.DYNAMIC,
service = ServiceA.class,
target = "(type=*)"
)
public void addServiceA(ServiceA instance, Map properties) {
service.put(String.valueOf(properties.get("type")), instance);
}
public void removeServiceA(Map properties) {
service.remove(String.valueOf(properties.get("type")));
}
// ...
}