【发布时间】:2020-09-22 20:12:28
【问题描述】:
我正在浏览 Google Guice 文档并阅读了有关 UntargettedBinding 的信息。基本上有两种选择
- @命名
- 绑定注解
我的问题是,哪个更好?
使用@Named,我不必创建样板来使用annotations,但它的代价是降低了类型安全性。恕我直言,注释代码看起来更干净。
【问题讨论】:
标签: java dependency-injection guice
我正在浏览 Google Guice 文档并阅读了有关 UntargettedBinding 的信息。基本上有两种选择
我的问题是,哪个更好?
使用@Named,我不必创建样板来使用annotations,但它的代价是降低了类型安全性。恕我直言,注释代码看起来更干净。
【问题讨论】:
标签: java dependency-injection guice
您通常按照here 的说明指定了绑定注释的优缺点。
你的说法是正确的。
@Named 的另一个优点是使用 Names.bindProperties 绑定属性。 使用绑定注释无关紧要。 见how to load properties
对于 UntargetBinding (这听起来像是真正的问题) 文档说明了两个选项
如果您不想使用绑定注解/@Named,只需声明绑定到具体类即可。
例如
bind(MyConcreteClass.class);
bind(AnotherConcreteClass.class).in(Singleton.class);
您需要使用绑定注释/@Named 您必须仍然添加目标绑定,即“.toSometing”方法(到, toProvider、toContractor 等)
例如:
public class TestUntargetBinding {
@Test
void testTargetBindingViaImplementBy() {
final var injector = Guice.createInjector(new AbstractModule() {
@Override
public void configure() {
bind(MyConcreteClass.class)
.annotatedWith(Names.named("100"))
.toProvider(() -> new MyConcreteClass(100));
bind(MyConcreteClass.class)
.annotatedWith(Names.named("200"))
.toProvider(() -> new MyConcreteClass(200));
}
});
//imagine a class with a constructor
// @Inject
// SomeClass(@Named("100) MyConcreteClass myConcreteClass1){...}
final var myConcreteClass1 = injector.getInstance(Key.get(MyConcreteClass.class, Names.named("100")));
final var myConcreteClass2 = injector.getInstance(Key.get(MyConcreteClass.class, Names.named("200")));
assertThat(myConcreteClass1.doSomething(), Is.is(100));
assertThat(myConcreteClass2.doSomething(), Is.is(200));
}
static class MyConcreteClass {
private int i;
public MyConcreteClass(int i) {
this.i = i;
}
public int doSomething() {
return i;
}
}
}
除非您指定“toProvider”
,否则Guice 将不知道将名称/注释绑定到的女巫类【讨论】:
Since the compiler can't check the string, we recommend using @Named sparingly. Defining your own purpose-built annotations provides better type-safety. 有人能解释一下它在谈论什么样的类型安全吗?