【问题标题】:How to write factory pattern in OSGi?如何在 OSGi 中编写工厂模式?
【发布时间】:2019-02-20 09:51:57
【问题描述】:

我有多个实现相同服务的 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;
         }
    }
}

【问题讨论】:

  • 您能否更详细地解释您为什么要这样做。通常你会将服务对象直接注入到实际需要使用它的类中。
  • 我需要为 serviceA 创建工厂。这就是我的意图。由于我是 OSGi 的新手,我以经典的方式想象一切。因此,如果根据 OSGi 有任何其他方式,请指导我。
  • 我确信您的应用程序的用户并不关心您使用的是工厂。正如我在之前的评论中所建议的,您可以将服务实例直接注入到实际需要它的地方。

标签: osgi service-factory


【解决方案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")));
    }

    // ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    相关资源
    最近更新 更多