辅助类作为Guice的单身人士

时间:2016-05-25 19:32:34

标签: java guice

我正在学习Google Guice。 我理解如何将接口绑定到它的实现。

现在,我有以下助手类:

class PersonHelper {
   public static FakeDatabaseConfiguration dbConfig;
   public PersonHelper(){
      if (dbConfig == null){
          dbConfig = new FakeDatabaseConfiguration();
          dbConfig.setHost('127.0.0.1');
          dbConfig.setPort('3306');
          dbConfig.setUsername('root');
          dbConfig.setPassword('root');
       }
   }

   public List<Person> getPersons(){
      FakeResult fakeResult = dbConfig.executeSQL("select * from Person");
      return fakeResult.asList();
   }
}

今天,我这样使用它:

PersonHelper personHelper = new PersonHelper();
List<Person> personsList = personHelper. getPersons();

我非常确定有一种方法可以让这个课程变得更好。

问题:如何使用Guice将此类作为单例进行制作,以便我不会在每个实例中延迟加载dbConfig变量? (我读到有一个@Singleton注释,但它在Guice中被视为范围。)

此致

3 个答案:

答案 0 :(得分:0)

请查看Binding @Provides method as eager singleton看看是否有帮助。 eagerSingleton部分可能适合您。

答案 1 :(得分:0)

将它作为范围完全你想要的东西:范围有效地告诉Guice什么时候允许重用它已经创建的同一个对象,以及{{1答案是&#34;总是&#34;。

如果您要列出这样的类:

@Singleton

然后类本身变成Singleton。每当实例化类时都会创建FakeDatabaseConfiguration,但是对于通过Guice的所有访问,只会发生一次。

当然,这些都不适用于直接构造函数调用@Singleton // Could also be in your module or @Provides method. class PersonHelper { private FakeDatabaseConfiguration dbConfig; public PersonHelper(){ dbConfig = new FakeDatabaseConfiguration(); dbConfig.setHost('127.0.0.1'); dbConfig.setPort('3306'); dbConfig.setUsername('root'); dbConfig.setPassword('root'); } public List<Person> getPersons(){ FakeResult fakeResult = dbConfig.executeSQL("select * from Person"); return fakeResult.asList(); } } ,但除了极少数例外,Guice只擅长对它提供的对象进行保证。 Guice可以控制的任何访问,包括通过new PersonHelper()getInstance - 带注释的字段和构造函数,只会看到PersonH​​elper(因此FakeDatabaseConfiguration)只创建一次。

答案 2 :(得分:0)

首先,在您的模块中,您必须声明一个提供程序(FakeDatabaseConfigurationProvider)。如上所述,这是注入配置对象的最佳方式。 然后,将您的助手类声明为Singleton并将其绑定在您的模块中。 这将允许您的助手类使用如下:

public class SomeClass{
  @Inject
  private PersonHelper personHelper;
  ...
  public void someMethod(){
    ...
    List<Person> personsList = personHelper.getPersons();
    ..
  }
}

同一个实例将通过您的应用分享。

以下是建议的代码:

public class MyModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(FakeDatabaseConfiguration.class).toProvider(FakeDatabaseConfigurationProvider.class);
    bind(PersonHelper.class).in(Scopes.SINGLETON);
  }

  /**
   * FakeDatabaseConfigurationProvider implementation
   */
  static class FakeDatabaseConfigurationProvider implements Provider<FakeDatabaseConfiguration> {

    @Override
    public FakeDatabaseConfiguration get() {
      FakeDatabaseConfiguration dbConfig = new FakeDatabaseConfiguration();
      dbConfig.setHost('127.0.0.1');
      dbConfig.setPort('3306');
      dbConfig.setUsername('root');
      dbConfig.setPassword('root');
      return dbConfig;
    }
  }
}

然后,在PersonHelper

public class PersonHelper{
    private FakeDatabaseConfiguration fakeDatabaseConfiguration;
    @Inject
    public PersonHelper(final FakeDatabaseConfiguration fakeDatabaseConfiguration){
        this.fakeDatabaseConfiguration = fakeDatabaseConfiguration;
    }

    public List<Person> getPersons(){
      FakeResult fakeResult = fakeDatabaseConfiguration.executeSQL("select * from Person");
      return fakeDatabaseConfiguration.asList();
    }

}