@Provides 和@Named 不适用于超类型声明的变量
@Provides with @Named doesn't work for supertype declared variables
我目前正在探索 Guice 功能并遇到了一个奇怪的行为 - 当我将变量声明为
@Inject
@Named("dragon")
Dragon dragon2;
注入按预期工作,但是当我想将 dragon2 声明为接口(它实现 Creature)时,我。 e.
@Inject
@Named("dragon")
Creature dragon2;
我收到一个错误
未绑定带有 @com.google.inject.name.Named(value=dragon)
注释的 warlock.rincewind.creatures.Creature 的实现。
这是我的提供者方法:
@Named("dragon")
@Provides
public Dragon providesDragon() {
Dragon d = new Dragon("Morkeleb");
return d;
}
我知道,有很多不同的方法可以克服这个问题(最简单的方法是更改为 Creature 提供 return 类型),但我正在尝试找出造成这种限制的原因。
考虑,例如:
interface Creature { }
class Dragon implements Creature { }
class Dog implements Creature { }
public class Kennel {
@Inject @Named("foo") Creature c;
}
public class KennelModule extends Abstract Module {
@Override
protected void configure() {
bind(Dragon.class).annotatedWith(Names.named("foo"));
bind(Dog.class).annotatedWith(Names.named("foo"));
}
}
您的注入如何知道是在此处绑定 Dragon
还是 Dog
?
不能! 注入密钥不是协变的。您需要做的是,指定您要注入的子类,并将其绑定到您要注入的接口或超类。 换句话说:
public class KennelModule extends Abstract Module {
@Override
protected void configure() {
bind(Creature.class).annotatedWith(Names.named("foo").to(Dragon.class);
}
}
这会给你想要的行为。当然,您仍然可以专门为 Dragon
绑定注入。
我目前正在探索 Guice 功能并遇到了一个奇怪的行为 - 当我将变量声明为
@Inject
@Named("dragon")
Dragon dragon2;
注入按预期工作,但是当我想将 dragon2 声明为接口(它实现 Creature)时,我。 e.
@Inject
@Named("dragon")
Creature dragon2;
我收到一个错误
未绑定带有 @com.google.inject.name.Named(value=dragon)
注释的 warlock.rincewind.creatures.Creature 的实现。
这是我的提供者方法:
@Named("dragon")
@Provides
public Dragon providesDragon() {
Dragon d = new Dragon("Morkeleb");
return d;
}
我知道,有很多不同的方法可以克服这个问题(最简单的方法是更改为 Creature 提供 return 类型),但我正在尝试找出造成这种限制的原因。
考虑,例如:
interface Creature { }
class Dragon implements Creature { }
class Dog implements Creature { }
public class Kennel {
@Inject @Named("foo") Creature c;
}
public class KennelModule extends Abstract Module {
@Override
protected void configure() {
bind(Dragon.class).annotatedWith(Names.named("foo"));
bind(Dog.class).annotatedWith(Names.named("foo"));
}
}
您的注入如何知道是在此处绑定 Dragon
还是 Dog
?
不能! 注入密钥不是协变的。您需要做的是,指定您要注入的子类,并将其绑定到您要注入的接口或超类。 换句话说:
public class KennelModule extends Abstract Module {
@Override
protected void configure() {
bind(Creature.class).annotatedWith(Names.named("foo").to(Dragon.class);
}
}
这会给你想要的行为。当然,您仍然可以专门为 Dragon
绑定注入。