[英]What's going on in this Guice example?
我有以下代码示例。
public interface Calculator {
public int compute(int a);
}
public class Adder implements Calculator {
private int n = 0;
@Override public int compute(int a) {
int result = a + n;
++n;
return result;
}
}
public class X {@Inject public void run(Calculator c) {
System.out.println(c.compute(500));
}
}
public class FirstModule extends AbstractModule {@Override protected void configure() {
bind(Calculator.class).to(Adder.class);
}
}
public static void main(String[] args) {
Injector inj = Guice.createInjector(new FirstModule());
X x1 = inj.getInstance(X.class);
x1.run(inj.getInstance(Calculator.class));
X x2 = inj.getInstance(X.class);
x2.run(inj.getInstance(Calculator.class));
System.out.println(x1 == x2);
}
我期望输出为:
500
500
False
而是:
500
500
500
500
False
似乎实例化行(如X x1 = inj.getInstance(X.class);
)执行run()
方法。 这是为什么?
Guice确实会调用run
,因为您告诉它:
public class X { /* here -> */ @Inject public void run(Calculator c) {
System.out.println(c.compute(500));
}
}
run方法的@Inject
注释使Guice认为这是一个设置器,因此当它在实例创建过程中注入成员时,会使用run
将计算器实例注入到您的类中。
请参阅文档 。
吉斯不仅注入构造,标注了@Inject
也与领域注解@Inject
和带注释的方法@Inject
。
例如(除了时间/顺序之外),这些示例导致相同的结果,即foo被注入:
class ConstructorInjection {
private String foo;
@Inject public ConstructorInjection(String foo) { this.foo = foo; }
}
class FieldInjection {
@Inject private String foo;
// default constructor not needed in this case
}
class MethodInjection {
private String foo;
// default constructor not needed in this case
@Inject
public void setFoo(String foo) { this.foo = foo; }
}
请注意,Guice并不暗示要注入的方法的任何命名约定(因此,设置程序setFoo
可能也被命名为run
或其他任何名称setFoo
将注入所有@Inject
注释的方法。
基本上,您正在使用第三种方法(MethodInjection),这将在创建实例时使Guice调用run
。
正如Girish在他/她的答案中所示,您必须在这种情况下使用构造函数注入(或字段注入),在类中为计算器提供一个字段,并从run方法中删除参数。
@Inject将执行您指定的构造函数/方法。 正确的使用方法是与构造函数一起注入Calc实例。
interface Calculator
{
public int compute(int a);
}
class Adder implements Calculator
{
private int n = 0;
@Override
public int compute(int a)
{
int result = a + n;
++n;
return result;
}
}
class X
{
private Calculator c;
@Inject
public X(Calculator c)
{
this.c = c;
}
public void run(Calculator c)
{
System.out.println(c.compute(500));
}
}
class FirstModule extends AbstractModule
{
@Override
protected void configure()
{
bind(Calculator.class).to(Adder.class);
}
}
public static void main(String[] args)
{
Injector inj = Guice.createInjector(new FirstModule());
X x1 = inj.getInstance(X.class);
x1.run(inj.getInstance(Calculator.class));
X x2 = inj.getInstance(X.class);
x2.run(inj.getInstance(Calculator.class));
System.out.println(x1 == x2);
}
输出:
500500错误
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.