我有以下代码示例。
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()
方法。这是为什么?
答案 0 :(得分:1)
Guice确实打电话给run
,因为你告诉它:
public class X { /* here -> */ @Inject public void run(Calculator c) {
System.out.println(c.compute(500));
}
}
run方法的@Inject
注释使Guice认为这是一个setter,因此当它在实例创建期间注入成员时,它会使用run
将一个计算器实例注入到您的类中。
请参阅documentation。
Guice不仅会注入使用@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并不暗示对要注入的方法有任何命名约定(因此setter setFoo
可能已被命名为run
或其他任何内容.Guice将注入所有注释为{{1}的方法}}
您基本上使用第三种方式(MethodInjection),这将导致Guice在创建实例时调用@Inject
。
正如Girish在他/她的回答中所示,你必须在你的案例中使用构造函数注入(或字段注入),在你的类中有一个计算器字段,并从run方法中删除参数。 / p>
答案 1 :(得分:1)
@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);
}
输出:
500 500 假