java - 如何使用 Guice 将参数传递给 Provider?

标签 java dependency-injection guice

假设我有这个界面:

public interface DbMapper{
}

然后这个实现:

public interface NameDbMapper extends DbMapper {

    @SqlUpdate("insert into names (name) values (:name)")
    void insert(@Bind("name") String name);
}

这个实现存在于一个模块中,所以编译时不知道所有的DbMappers。我通过反射(reflection)发现了 DbMappers:

public class GuiceModule extends AbstractModule{

    @Override
    protected void configure() {
        Reflections reflections = new Reflections("com.company");
        Set<Class<? extends DbMapper>> dbMappers = reflections.getSubTypesOf(DbMapper.class);

        for (Class<? extends DbMapper> dbMapper : dbMappers) {
            Class<DbMapper> db = (Class<DbMapper>) dbMapper;
            binder().bind(db).toProvider(DbMapperProvider.class);
        }
    }

然后我在我的提供者中实例化映射器:

public class DbMapperProvider implements Provider<DbMapper> {

    private final User user;

    @Inject
    public DbMapperProvider(User user) {
        this.user = user;
    }

    @Override
    public DbMapper get() {
        String jdbc = user.getJdbc();

        DBI userSpecificDatabase = new DBI(jdbc, "user", "password");
        //How to replace NameDbMapper.class here with the db variable in GuiceModule?
        DbMapper dbMapper = userSpecificDatabase.onDemand(NameDbMapper.class);
        return dbMapper;
    }
}

User 是一个@RequestScoped 实例,因此我无法在 GuiceModule 中定期创建提供者。注入(inject)用户有效,但我如何在此处传递 DBI 应使用的类而不是硬编码 DbMapperProvider 中的 NameDbMapper?

我已经尝试了 http://google-guice.googlecode.com/git/javadoc/com/google/inject/assistedinject/FactoryModuleBuilder.html 中建议的方法但无法让它工作。

这里的目标是模块不必编写自己的提供程序,这可以实现吗?

最佳答案

你可以绑定(bind)到一个提供者实例,比如

for (Class<? extends DbMapper> dbMapper : dbMappers) {
    bind(dbMapper).toProvider(new DbMapperProvider<>(db));
}

然后像这样修改你的提供者:

public class DbMapperProvider<T extends DbMapper> implements Provider<T> {
    // Use field or method injection
    @Inject
    private Provider<User> user;

    private final Class<T> type;

    public DbMapperProvider(Class<T> type) {
        this.type = type;
    }

    @Override
    public T get() {
        String jdbc = user.get().getJdbc();

        DBI userSpecificDatabase = new DBI(jdbc, "user", "password");
        DbMapper dbMapper = userSpecificDatabase.onDemand(type);
        return dbMapper;
    }
}

关于java - 如何使用 Guice 将参数传递给 Provider?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24030609/

相关文章:

java - 动态内容解析

Java 泛型异常会产生编译时错误

c# - Ninject NamedScope 条件绑定(bind)

java - 指南 : Set bindings from an XML file

c# - 如何在 XUnit 中使用 AddTransient 方法注入(inject) 'Microsoft.Extensions.Configuration.IConfiguration'

java - 将字符串列表附加到 Android 外部存储中的文本文件末尾

java - 二维数组和 JApplet : button visibility and label change

jersey - 使用 Jersey 的 ExceptionMapper 映射 Shiro 的 AuthenticationException

java - Junits 的 Guice 和 Mockto

java - 命名字符串字段上的 Guice 注入(inject)