当前位置:  开发笔记 > 编程语言 > 正文

使用guice将运行时参数传递给构造函数

如何解决《使用guice将运行时参数传递给构造函数》经验,为你挑选了1个好方法。

如果我有以下课程:

public class ObjectDAOMongoDBImpl extends GenericDAOMongoDBImpl implements ObjectDAO {
    public ObjectDAOMongoDBImpl(Class entityClass, Mongo mongo, Morphia morphia, String dbName) {
        super(entityClass, mongo, morphia, dbName);
    }
}

其中,entityClass提供在运行时-我该如何使用吉斯到上述类型的接口绑定?

public class RunnerModule extends AbstractModule {      
    @Override
    protected void configure() {
        bind(GenericDAO.class).to(ObjectDAOMongoDBImpl.class);
    }
}

public class Runner {
    GenericDAO dao;

    @Inject
    public Runner(GenericDAO dao) {
        this.dao = dao;
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new RunnerModule());
        injector.getInstance(Runner.class);
    }
}

可以定义mongo,morphiadbName作为文字RunnerModule(是否有更简洁的方法?),但我无法知道什么entityClass是运行时.



1> Kohányi Róbe..:

这不是Guice惯用的,也不是它的主要焦点.

jfpoilpret已经说了所有可以说的,但我想从另一个方向解决问题,你可以选择(可能)通过失去类型安全来解决你的问题.

因此,在您的代码中,您要求Guice Runner像这样获取您的类的实例

injector.getInstance(Runner.class);

但Guice无法解决这个问题,因为Runner它具有依赖性GenericDAO,但您没有绑定它的确切实现.正如jfpoilpret所说,你必须在你的模块中为它绑定一些具体的实现.

我猜你想根据一些输入数据确定GenericDAO传递给你的确切实现Runner,这些数据的类型在编译时是未知的.现在,我们假设您有两个实现.

bind(new TypeLiteral>(){}).to(StringDAO.class);
bind(new TypeLiteral>(){}).to(IntegerDAO.class);

根据不同类型的输入,您可以执行此操作

Injector injector = Guice.createInjector(new RunnerModule());

// possible input which you get from *somewhere* dynamically
Object object = 1.0;

TypeLiteral matchedTypeLiteral = null;
for (Key key : injector.getAllBindings().keySet()) {
  TypeLiteral typeLiteral = key.getTypeLiteral();
  Type type = typeLiteral.getType();
  if (type instanceof ParameterizedType) {
    ParameterizedType parameterizedType = (ParameterizedType) type;
      if (parameterizedType.getRawType() == GenericDAO.class) {
        List actualTypeArguments =    Arrays.asList(parameterizedType.getActualTypeArguments());
        if (actualTypeArguments.get(0) == object.getClass())
          matchedTypeLiteral = typeLiteral;
    }
  }
};

Runner runner = new Runner<>((GenericDAO) injector.getInstance(Key.get(matchedTypeLiteral)));
System.out.println(runner.dao.getClass()); // IntegerDAO.class

如果Object object = "string";,那么将找到其他实现.这当然相当丑陋,可以通过检查子类和东西来改进,但我认为你明白了.最重要的是你无法解决这个问题.

如果你设法做到(绕过它),请给我发电子邮件,因为我想知道它!我不久前遇到了同样的问题.我写了一个简单的BSON编解码器,我想根据某些任意输入的类型加载通用接口的特定实现.这适用于Java-to-BSON映射,但我不能以任何合理的方式做到这一点,所以我选择了一个更简单的解决方案.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有