par*_*tic 28 java dependency-injection guice
我正在尝试迁移一个小项目,用Guice替换一些工厂(这是我的第一个Guice试验).但是,在尝试注射仿制药时,我陷入困境.我设法提取了一个带有两个类和一个模块的小玩具示例:
import com.google.inject.Inject;
public class Console<T> {
private final StringOutput<T> out;
@Inject
public Console(StringOutput<T> out) {
this.out = out;
}
public void print(T t) {
System.out.println(out.converter(t));
}
}
public class StringOutput<T> {
public String converter(T t) {
return t.toString();
}
}
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(StringOutput.class);
bind(Console.class);
}
public static void main(String[] args) {
Injector injector = Guice.createInjector( new MyModule() );
StringOutput<Integer> out = injector.getInstance(StringOutput.class);
System.out.println( out.converter(12) );
Console<Double> cons = injector.getInstance(Console.class);
cons.print(123.0);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个例子时,我得到的只是:
线程"main"中的异常com.google.inject.CreationException:Guice创建错误:
1) playground.StringOutput<T> cannot be used as a key; It is not fully specified.
at playground.MyModule.configure(MyModule.java:15)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354)
at com.google.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:152)
at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:105)
at com.google.inject.Guice.createInjector(Guice.java:92)
Run Code Online (Sandbox Code Playgroud)
我尝试查找错误消息,但没有找到任何有用的提示.关于Guice常见问题,我偶然发现了一个关于如何注射仿制药的问题.我试图在configure方法中添加以下绑定:
bind(new TypeLiteral<StringOutput<Double>>() {}).toInstance(new StringOutput<Double>());
Run Code Online (Sandbox Code Playgroud)
但没有成功(相同的错误信息).
有人可以解释我的错误信息,并提供一些提示吗?谢谢.
Col*_*inD 28
我认为您所看到的具体问题可能是因为该bind(Console.class)声明.它也应该使用a TypeLiteral.或者,你可以只绑定那些和JIT绑定将为你处理它,因为这里涉及的两种类型都是具体的类.
此外,您应该检索Console:
Console<Double> cons =
injector.getInstance(Key.get(new TypeLiteral<Console<Double>>(){}));
Run Code Online (Sandbox Code Playgroud)
编辑:您不需要仅仅因为使用了一个而绑定到实例TypeLiteral.你可以这样做:
bind(new TypeLiteral<Console<Double>>(){});
Run Code Online (Sandbox Code Playgroud)
当然,就像我上面所说的那样,你可以在这种情况下跳过它,并Console使用Key基于它的注入器检索,TypeLiteral并且绑定将是隐式的.