如何正确创建和关闭功能

时间:2016-07-04 09:37:01

标签: java guice

我正在开发一个可以由用户启用和禁用的功能。 它在一个单独的模块中实现,它创建了一些线程和一些单例。 由于我有一个单独的模块,因为我们打算稍后在一个单独的过程中运行它,我使用了一个单独的guice注入器。 所以我有一个工厂方法创建注入器并返回一个实现功能接口的类(它有3个接口)

public class FeatureFactory {
    private Injector injector;
    public FeatureClass open() {
        injector = createInjector();
        return injector.getInstance(FeatureClass.class);
    }
}

public class FeatureClass implements InterfaceA, InterfaceB, InterfaceC {

}

问题:

  1. 在这种情况下创建新的注射器是一种好习惯吗?我的意思是整个功能都在一个单独的模块中? 我们的想法是将它们分离,而不是将新功能guice模块作为功能API的一部分。如果不是,那会是更好的方法吗?
  2. 返回要素类而不是接口并不好闻。 它让用户了解实现 我该如何克服这个问题? 目前,我使用应用程序guice模块将接口绑定到FeatureClass
  3. 如何关闭该功能并将所有类别的垃圾收集起来? 正如我所说,当功能打开时,会创建一些单例和线程。 如果我将进样器字段设为null,这是否意味着所有内容都被垃圾收集了?

1 个答案:

答案 0 :(得分:1)

创建多个注射器通常是个坏主意。单身人士使用注射器,因此当您创建多个注射器时,您的单身人士不再是单身人士。

相反,创建一个工厂类,允许调用者创建类的实例,并向该工厂注入Provider<FeatureClass>

@Singleton
public class FeatureClassFactory {
  private final Provider<FeatureClass> provider;
  private FeatureClass instance;

  @Inject
  FeatureClassFactory(Provider<FeatureClass> provider) {
    this.provider = provider;
  }

  public synchronized FeatureClass get() {
    if (instance == null) {
      instance = provider.get();
    }
    return instance;
  }
}

当然,您可以使用单例Provider<FeatureClass>作为API,而不是创建工厂,但1)我不喜欢在我的公共API中使用Guice接口,2)在生产模式中,单例是在初始化注入器时创建,并且您表示要延迟创建FeatureClass实例。

至于返回一个实现与一个类,哪个更好是一个争论的问题,取决于用例和编码风格。

最后,由于单身人士使用注射器确定范围,因此注射器对所有单身人士保持强有力的参考。如果您需要在应用程序的生命周期内释放内存,则必须通过将字段设置为null和/或清除集合来让您的类释放内存。