使用 Guice 创建和初始化单例

Create and initialize a singleton with Guice

我有以下 classes StorageProxy.java(界面) StorageProxyImpl1.java(StorageProxy接口的实现1)

public class StorageProxyImpl1 extends StorageProxy{
    public void init(String key){
      ....
    }
}

public class Resource1{
    private StorageProxy sp;
    ...
}

public class Resource2{
    private StorageProxy sp;
    ...
}

我在应用程序 class 中有一个主要方法,用于初始化和使用 Resource1 和 Resource2。

public class MyApp{
  public static void main(String args[]){
    Resource1 r1 = new Resource1();
    Resource2 r2 = new Resource2();
    runApp(r1,r2);
  }
  public void runApp(Resource1 r1, Resource2 r2){ // Makes use of r1 and r2
    ...
  }
}

我想指导 StorageProxy 的依赖注入,这样我在创建新实现时就不会很痛苦。我希望 Resource1 和 Resource2 使用相同的 StorageProxy 对象(即它应该是 Singleton)。 init 与构造函数分开是至关重要的。总而言之,我需要创建一个 StorageProxyImpl1 的实例并在 main 方法中对其调用 StorageProxyImpl1.init(String),并且该实例应由 Resource1 和 Resource2 共享。如何做到这一点?

Guice: How to get instance of Singleton without injector or using Constructor Injection问的问题有点高,没有具体的例子我觉得很难理解。

您可以使用 provider interface

public class StorageProxyProvider implements Provider<StorageProxy> {
   public StorageProxy get() {
      StorageProxy storageProxy = new StorageProxy();
      storageProxy.init();
      return storageProxy;
   }
}

public class StorageProxyModule extends AbstractModule {
   protected void configure() {
     bind(StorageProxy.class).toProvider(StorageProxyProvider.class).in(Singleton.class);
   }
}

一个工作示例:

public class StorageProxyProvider implements Provider<StorageProxy> {

    public StorageProxy get() {
        StorageProxy storageProxy = new StorageProxy();
        storageProxy.init();
        return storageProxy;
    }

}


public class StorageProxy {

    public void init(){
        System.out.println("init");
    }
    public void proxy(){
        System.out.println("proxy");
    }

}

public class StorageProxyModule extends AbstractModule {
    protected void configure() {
        bind(StorageProxy.class).toProvider(StorageProxyProvider.class).in(Singleton.class);
    }
}


public class Example {
    @Inject
    StorageProxy storageProxy;

    public void doSomethingThatNeedStorageProxy() {
        System.out.println(storageProxy);
        storageProxy.proxy();
    }

}

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new StorageProxyModule());
        Example e = injector.getInstance(Example.class);
        e.doSomethingThatNeedStorageProxy();
        e = injector.getInstance(Example.class);
        e.doSomethingThatNeedStorageProxy();
    }
}