有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java助手类作为带有Guice的单例

我正在学习谷歌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) 个答案

  1. # 1 楼答案

    将它作为作用域正是您想要的:作用域有效地告诉Guice何时允许重用已创建的同一对象,对于@Singleton来说,答案是“始终”

    如果您要这样列出该类:

    @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();
      }
    }
    

    然后类本身成为一个单例。只要实例化该类,就会创建FakeDatabaseConfiguration,但对于通过Guice进行的所有访问,这只会发生一次

    当然,这些都不适用于作为new PersonHelper()的直接构造函数调用,但除了少数例外,Guice只擅长保证它提供的对象。Guice可以控制的任何访问,包括通过getInstance@Inject注释字段和构造函数进行的访问,将只看到PersonHelper(因此FakeDatabaseConfiguration)创建一次

  2. # 3 楼答案

    首先,在模块中,必须声明一个提供程序(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();
        }
    
    }