1

次のコード例があります。

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()です。何故ですか?

4

2 に答える 2

1

Guice は実際に を呼び出しrunます。

public class X { /* here -> */ @Inject public void run(Calculator c) {
        System.out.println(c.compute(500));
    }
}

run メソッドの@Injectアノテーションにより、Guice はこれがセッターであると認識し、runインスタンスの作成中にメンバーを注入するときに、 を使用して電卓インスタンスをクラスに注入します。

ドキュメントを参照してください。

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 は、@Inject.

run基本的に、インスタンスの作成時にGuice を呼び出す 3 番目の方法 (MethodInjection) を使用しています。

Girish が回答で示しているように、コンストラクター注入 (またはフィールド注入) を使用し、クラスに電卓用のフィールドを用意し、run メソッドからパラメーターを削除する必要があります。

于 2014-07-17T09:56:53.420 に答える