Guice是否支持方法注入(非二次注入)?

时间:2014-07-17 10:53:49

标签: java dependency-injection guice

根据我的理解,Guice支持注入:构造函数,Setter(由于某种原因它们称为方法注入),字段。

它还可以注入方法参数吗?例如:

void foo(InterfaceA a, InterfaceA a1){
    ...
}


interface InterfaceA{
    ...
}


class A implements InterfaceA{
    ....
}

class B implements InterfaceA{
    ....
}

我希望能够将a中的foo绑定到A,将a1绑定到B(可能需要注释,但我们可以忽略它一秒)。 我希望在调用上完成此操作。

这似乎与正常用例(c'tor,fields,setters)不同,因为依赖注入将在调用时发生而不是在对象创建上发生。

这可能吗?

2 个答案:

答案 0 :(得分:6)

Vladimir's answer是正确的,但您可以使用字段注入和Providers更简洁地执行相同操作,并检查在注入器创建时是否满足依赖性,而不是注入注入器。 此代码与他的代码相同,但已修改为使用提供程序:

Injector injector = Guice.createInjector(b -> {
    b.bind(InterfaceA.class).annotatedWith(Names.named("a")).to(A.class);
    b.bind(InterfaceA.class).annotatedWith(Names.named("a1")).to(B.class);
    b.bind(Invoke.class);
});

public class Invoke {
    // Constructor injection works too, of course. These fields could also be
    // made private, but this could make things difficult to test.
    @Inject @Named("a") Provider<InterfaceA> aProvider;
    @Inject @Named("a1") Provider<InterfaceA> a1Provider;

    public void invoke() {
        this.foo(aProvider.get(), a1Provider.get());
    }

    void foo(InterfaceA a, InterfaceA a1){
        ...
    }
}

答案 1 :(得分:3)

嗯,你可以这样做:

Injector injector = Guice.createInjector(b -> {
    b.bind(InterfaceA.class).annotatedWith(Names.named("a")).to(A.class);
    b.bind(InterfaceA.class).annotatedWith(Names.named("a1")).to(B.class);
    b.bind(Invoke.class);
});


public class Invoke {
    private final Injector injector;

    @Inject
    Invoke(Injector injector) {
        this.injector = injector;
    }

    public void invoke() {
        this.foo(
            injector.getInstance(Key.get(InterfaceA.class, Names.named("a"))),
            injector.getInstance(Key.get(InterfaceA.class, Names.named("a1")))
        );
    }

    void foo(InterfaceA a, InterfaceA a1){
        ...
    }
}

但仅此而已。 Guice是一个依赖 injection 框架,它通常意味着&#34; 构造对象及其所有依赖关系&#34;。虽然方法参数依赖正式(因为类应该使用它们 - 这是依赖的定义),但它们通常不被DI框架视为那些。这是可以理解的 - 这会使这些框架变得更加复杂,几乎没有任何收获,而且Java也没有足够的表达能力来表达这些看起来不那么丑陋的东西。