在给定捆绑中引用OSGi DS的最佳实践

时间:2012-10-25 09:30:18

标签: osgi declarative-services

我的要求: 我有一个服务,负责我的项目中的持久性。让我将此服务称为PersistenceProvider服务,并假设它位于“my.persistenceservice”包中。

现在,我有另一个名为“my.persitenceconsumer”的bundle,它使用名为MyPersistenseConsumer的类之一的bind()unbind()方法引用PersistenceProvider服务。因此,当“my.persistenceconsumer”包启动时,它将使用bind()方法获取PersistenceProvider服务的引用,MyPersistenceConsumer可以使用PersistenceProvider服务

但是,我还需要在“my.persitenceconsumer”包中使用来自不同类的PersistenceProvider服务。

我的问题是: 在不同类(在同一个包中)中使用此类共享服务的最佳方法是什么

其中一个解决方案: 我可以在“my.persitenceconsumer”包中添加Activator类。使用静态getInstance()方法。这可以通过MyPersistenceConsumer.bind()调用,并将PersistenceProvider与Activator一起存储。后来“my.persitenceconsumer”包中的所有类都可以使用ActivistenceProvider使用Activator类。

以下是代码:

public class MyPersistenceConsumer {
  public void bindPersistenceProvider(PersistenceProvider ppRef) {
    MyPersistenceConsumerActivator.getInstance().bindPersistenceProvider(ppRef);
  }
}

public class MyPersistenceConsumerActivator {
  static MyPersistenceConsumerActivator instance;
  PersistenceProvider ppRef;

  public static getInstance() {
    return instance;
  }

  public void bindPersistenceProvider(PersistenceProvider ppRef) {
    this.ppRef = ppRef;
  }
  public PersistenceProvider getPersistenceProvider() {
    return ppRef;
  }

  public void start(BundleContext context) throws Exception {
        instance = this;
  }
}

public class MyClass1 {

  public void usePersistenceProvider(){
    PersistenceProvider pp Ref =
      MyPersistenceConsumerActivator.getInstance().getPersistenceProvider();
  }

}

public class MyClass2 {

  public void usePersistenceProvider(){
    PersistenceProvider pp Ref =
      MyPersistenceConsumerActivator.getInstance().getPersistenceProvider();
  }

}

最后: 以上是好方法......还是有更好的方法?

2 个答案:

答案 0 :(得分:2)

我建议有两种可能性:

  • 创建使用持久性服务声明性服务的对象。 SCR将处理所有生命周期管理,您将获得非常模块化和可测试的类。
  • 或者,您可以在这些对象的构造函数中传递对persistence-service的引用。这里唯一的问题是你必须确保这些对象在它消失后不会尝试访问持久性服务。

这些方法中的任何一种都优于您提出的基于单例的解决方案。

答案 1 :(得分:2)

单身人士是DS试图消除的邪恶。单身人士创造脆弱的系统,他们与全球变革有着同样的问题。

最佳解决方案是无耦合。使用DS我会使用:

@Component
public class MyClass1 {
  @Reference
  void setPP( PersistenceProvider pp ) { ... }
}

MyClass2也一样。如果类之间存在实例关系,则传递该对象,因为您已经耦合了。与往常一样,最小化耦合并最大化凝聚力。

工厂和单身是OSGi试图以非常好的理由阻止的确切罪恶。