注入具有泛型类型@Inject Guice的类时出错

时间:2017-01-14 14:41:06

标签: java generics dependency-injection guice inject

我正在尝试使用带有@Inject注释的Guice在另一个类(比如ClassB)中注入一类Generic类型(比如ClassA)。正在注入的类的代码如下所示:

public interface InterfaceA<T> {

}

public class ClassA<T> implements InterfaceA<T> {
    private final Class<T> data;
    private Dependency1 dependency1;

    @Inject
    public ClassA(Class<T> data, Dependency1 dependency1) {
        this.data = data;
        this.dependency1 = dependency1;
    }

}

ClassB代码如下:

public class ClassB {
    private InterfaceA<Entity1> interfaceA;

    @Inject
    public ClassB(InterfaceA<Entity1> interfaceA) {
        this.interfaceA = interfaceA;
    }
}

模块类如下:

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(new TypeLiteral<InterfaceA<Entity1>>(){}).to(new TypeLiteral<InterfaceA<Entity1>>(){});
    }
}

但是,当应用程序启动时,它会出现以下错误:

ERROR [2017-01-14 19:54:00,646] com.hubspot.dropwizard.guice.GuiceBundle: Exception occurred when creating Guice Injector - exiting
! com.google.inject.CreationException: Unable to create injector, see the following errors:
! 
! 1) Could not find a suitable constructor in java.lang.Class. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
!   at java.lang.Class.class(Class.java:119)

如何解决这个问题的任何输入都会非常有用。提前谢谢。

2 个答案:

答案 0 :(得分:2)

您无法以声明方式执行此操作。您必须使用提供程序方法:

function renderHTML(data)
{
   var htmlString = "<table style='width:100%'><tr><th>Location</th><th>Temperature</th><th>Humidity</th></tr>";
   for (i = 0; i < data.length; i++){
      console.log(i);
      htmlString += "<tr><td>"+ data[i].location + "</td><td>" + data[i].temperatureInC + "&deg;C/ " + data[i].temperatureInF + "&deg;F </td> <td> " + data[i].humidity + "</td></tr>";
   htmlString += "</table>"
   console.log(htmlString);
   sensorDataContainer.insertAdjacentHTML('beforeend', htmlString);
   }
}

这是唯一的方法,因为您无法在public class MyModule extends AbstractModule { @Override protected void configure() {} @Provides InterfaceA<Entity1> provideInterfaceAEntity1(Dependency1 dep) { return new ClassA<Entity1>(Entity1.class, dep); } } 中自动注入Class<T>

对于要与ClassA结合的每个Module,您需要Entity中的这种方法。

答案 1 :(得分:1)

我终于找到了解决方案。在这里,我没有在ClassA的构造函数中注入Class<T> data,而是使用它TypeLiteral<T> literal方法注入getRawType()并从TypeLiteral读取类类型。

ClassA的代码如下:

public class ClassA<T> implements InterfaceA<T> {
    private final Class<? super T> data;
    private Dependency1 dependency1;

    @Inject
    public ClassA(TypeLiteral<T> literal, Dependency1 dependency1) {
        this.data = literal.getRawType();
        this.dependency1 = dependency1;
    }
}

其他类的其余代码与以前一样。