Google Guice 命名与注释

Google Guice Named vs Annotation

我正在浏览 Google Guice 文档并阅读有关 UntargettedBinding 的内容。基本上有两种选择

  1. @Named
  2. 绑定注解

我的问题是,哪个更好?

使用 @Named 我不必创建样板来使用 annotations 但它的代价是类型安全性较低。注释代码看起来更简洁恕我直言。

您按照解释here
概括地指定了绑定注释的优点和缺点 你的说法是正确的。

@Named 的另一个优点是使用 Names.bindProperties 绑定属性。 在何处使用绑定注释无关紧要。 参见 how to load properties

对于 UntargetBinding (这听起来像是实际问题) 文档说明了两个选项

如果您不想使用绑定注释/@Named,只需将绑定声明到具体 class。
例如

bind(MyConcreteClass.class);
bind(AnotherConcreteClass.class).in(Singleton.class);

需要使用绑定注释/@Named 您必须仍然添加目标绑定,即“。 toSometing" 方法(to、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;
        }
    }
}

Guice 不会知道 class 将 name/annotation 绑定到,除非您指定“toProvider