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 - 如何将动态json值映射到Pojo中的HashMap

java - Bean属性dataSource在Spring + Hibernate 3中不可写(因无法添加更多代码而重新发布)

Java 和注入(inject)防御副本

java - 使用 CDI 在运行时创建和连接相关实例

java - 创建不与注入(inject)器绑定(bind)的 Guice 单例

java - Guice 通过属性(外部文本文件中的字符串)/运行时更改绑定(bind)

spring - 如何使用@Configuration的现有实例创建注释配置的Bean?

java - getBooleanSmart 更好的解析器

java - 为什么这个程序的空间复杂度是O(h)?其中 h 是 btree 的高度

python - 如何做依赖注入(inject)python-way?