【问题标题】:Guice assisted injection for typed classes类型化类的 Guice 辅助注入
【发布时间】:2019-02-11 06:21:07
【问题描述】:

我正在尝试在 Guice 中进行辅助注射。

这是我的实现。

public interface Dao<T> {
    T get(String id);
}

public class DaoImpl<T> implements Dao<T> {
    private final Class<T> clazz;
    DaoImpl(@Assisted final Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override 
    public T get() {
      //Some impl code
      return T;
    }
}

工厂界面。

public interface DaoFactory {
    <T> Dao<T> getDao(Class<T> clazz);
}

Guice 模块:

public class DaoModule extends AbstractModule {

    @Override
    protected void configure() {
        install(new FactoryModuleBuilder()
                .implement(new TypeLiteral<Dao<? extends Entity>>() {},
                        new TypeLiteral<DaoImpl<? extends Entity>>() {})
                .build(DaoFactory.class));
    }
}

我收到错误:“DaoFactory 不能用作键;它没有完全指定”。

我应该如何配置 FactoryModuleBuilder?

我的目标是在运行时使用 DaoFactory 获得一个类型化的 Dao 实例

【问题讨论】:

    标签: java guice


    【解决方案1】:

    辅助注入期望有一个绑定来选择您想要返回给您的内容 - 您的工厂接口的参数必须只是所需实现的构造函数中的 @Assisted-annotated 参数。

    在这种情况下,这意味着为了让DaoFactory.getDao 获取T,那么DaoImpl&lt;T&gt; 的构造函数将需要获取T 实例(用@Assisted 注释),然后这足以让DaoImpl 实例能够正确构建实例。可能是这样的:

    public class DaoImpl<T> implements Dao<T> {
    
        public DaoImpl(@Assisted T instance) {
            // Do something with the instance so this Dao is wired up right.
            // perhaps with instanceof or instance.getClass()?
        }
    
        @Override 
        public T get() {
          //Some impl code
          return T;
        }
    }
    

    所有辅助注入都知道该怎么做 - 以某种方式创建运行时查找并不是什么魔法,但这对您来说可能就足够了,具体取决于您的用例。我不确定为什么DaoFactory.getDao 会采用T 的实例,然后Dao.get() 也会返回T,但由于这是问题中示例代码的一部分,我猜你已经计划好了。


    编辑后更新:

    DaoFactory.getDao 采用 T 实例,但 DaoImpl 的构造函数是 DaoImpl(@Assisted final Class&lt;T&gt; clazz) - 辅助注入工厂必须采用预期传递给构造函数的相同参数。这对您的问题来说是个好消息 - 您只需稍微更改您的工厂声明:

    public interface DaoFactory {
        <T> Dao<T> getDao(Class<T> obj);
    }
    

    现在您调用getDao 并使用MyEntity.class 之类的参数作为参数,并将获得一个Dao&lt;MyEntity&gt; 实例,该实例是由guice 内部调用new DaoImpl(MyEntity.class) 创建的。

    如果您希望它特定于某个对象,则调用 instance.getClass() 并将其传入将产生一些您应该理解的泛型效果,因为 getClass() 实际上返回一个 Class&lt;?&gt;,或者最多返回一个 Class&lt;? extends WhateverMyDeclaredTypeIs&gt;。考虑以下几点:

    class MyClass {}
    class MySubclass extends MyClass{}
    
    MyClass foo = new MySubclass();
    
    factory.getDao(foo.getClass());// the generics will be a Dao<? extends MyClass>, 
    // not a Dao<MySubclass>, even though the DaoImpl.clazz holds an instance
    // of MySubclass
    

    【讨论】:

    • 我确实在构造函数中提供了辅助参数。我已经在上面更新了。在一个类中,我想要一个 DaoFactory 的实例。我想通过传递一个类型在运行时获取一个实例。 (在运行时,我想通过 factory.get(String.class) 来获取 Dao)。
    • 我试过这个并得到错误“DaoFactory 不能用作键;它没有完全指定”。我已经用我的模块和工厂更改更新了问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多