这个Guice示例中发生了什么?

时间:2014-07-17 09:48:56

标签: java guice guice-3

我有以下代码示例。

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()方法。这是为什么?

2 个答案:

答案 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 假