4

Provider我正在尝试为使用 JDBI 创建的 DAO设置一个。JDBI 使用一个Handle对象(它是 JDBC 的包装器Connection),您可以通过使用handle.attach(MyDaoType.class). 不必Provider为每个 DAO 类编写单独的实现,我认为这样做是有意义的:

public class DaoProvider<T> implements Provider<T> {

  private final Class<T> daoType;
  private final Handle handle;

  @Injected 
  public DaoProvider(Class<T> daoType, Handle handle) {
    this.daoType = daoType;
    this.handle = handle;
  }

  @Override
  public T get() {
    return handle.attach(daoType);
  }
}

但似乎很难将其与 Guice 联系起来。我尝试按照此答案@Assisted中的建议在第一个构造函数参数上使用注释。我定义了一个这样的工厂:

public interface DAOProviderFactory {
  <T> DAOProvider<T> create(Class<T> daoType);
}

但不清楚我应该如何调用该FactoryModuleBuilder.implemented方法,因为重点是我不想扩展我的提供程序类。

我有一个工厂,它返回一个返回我真正想要的东西的提供者,这似乎也有点疯狂!

让我感到震惊的是,使用 Spring DI 容器真的很容易做到这一点,所以我想相信使用 Guice 是可能的。谁能指出我正确的方向?

4

2 回答 2

3

感谢@condit 为我指出了一些使我能够解决问题的东西。其实很简单。我将Provider实现更改为使用字段注入,Handler如下所示:

public class DAOProvider<T> implements Provider<T> {

  private @Inject Handle handle;
  private final Class<T> daoType;

  public DAOProvider(Class<T> daoType) {
    this.daoType = daoType;
  }

  @Override public T get() {
    return handle.attach(daoType);
  }
}

然后在我想要绑定特定 DAO 类的任何模块或应用程序中,我可以执行以下操作:

bind(UserStore.class).toProvider(new DAOProvider<>(UserStore.class));
bind(MessageStore.class).toProvider(new DAOProvider<>(MessageStore.class));

Guice 然后自动将 注入HandleDAOProvider实例中。

于 2014-06-19T13:31:33.807 回答
0

我认为你把这件事弄得太复杂了。当您调用该get()方法时,您将结果存储在引用中,这意味着您知道特定 DAO 的类型,这意味着您可以编写知道 DAO 类的代码。我的意思是,想想 Guice 本身是如何工作的,你调用Injector.getInstance(Class<?> type)... 换句话说,这样的方法不能在没有你传递的情况下推断类型Class,所以Class在你使用它的时候传递!

我可以理解为什么你可能不想Handle直接注入,所以为什么不做一个包装器,例如

public interface DaoProvider {
  <T> T provideDao(Class<T> daoType);
}

接着:

public class JdbiDaoProvider implements DaoProvider {
  private final Handle handle;

  @Inject
  JdbiDaoProvider(Handle handle) {
    this.handle = handle;
  }

  public <T> T provideDao(Class<T> daoType) {
    return handle.attach(daoType);
  }
}
于 2014-06-18T17:36:27.473 回答