根据我的理解,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)不同,因为依赖注入将在调用时发生而不是在对象创建上发生。
这可能吗?
答案 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也没有足够的表达能力来表达这些看起来不那么丑陋的东西。