我尝试为使用JDBI创建的DAO设置Provider
。 JDBI使用Handle
对象(它是JDBC Connection
的包装器),您可以使用handle.attach(MyDaoType.class)
来获取DAO。而不是必须为每个DAO类编写单独的Provider
实现,我认为这样做是有道理的:
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联系似乎非常困难。我已经尝试使用this answer中建议的第一个构造函数参数上的@Assisted
注释。我定义了这样的工厂:
public interface DAOProviderFactory {
<T> DAOProvider<T> create(Class<T> daoType);
}
但我不清楚我应该如何调用FactoryModuleBuilder.implemented
方法,因为重点是我不想扩展我的提供程序类。
我有一个工厂返回提供商并返回我真正想要的东西,这似乎有点疯狂!
让我感到震惊的是,使用Spring DI容器真的很容易,所以我想相信Guice可以做到这一点。有人能指出我正确的方向吗?
答案 0 :(得分: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会自动将Handle
注入DAOProvider
个实例。
答案 1 :(得分:0)
我认为你这太复杂了。当您调用get()
方法时,您将结果存储在引用中,这意味着您知道特定DAO的类型,这意味着您可以在知道DAO类的情况下编写代码。我的意思是,想想Guice本身是如何工作的,你调用Injector.getInstance(Class<?> type)
...换句话说,这样的方法无论如何都不能推断出Class
,所以传递{{1当你使用它时!
我可以理解为什么你可能不想直接注入Class
,所以为什么不做一个包装器,例如。
Handle
然后:
public interface DaoProvider {
<T> T provideDao(Class<T> daoType);
}