[英]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.