【问题标题】:Google Guice Named vs AnnotationGoogle Guice 命名与注释
【发布时间】:2020-09-22 20:12:28
【问题描述】:

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

  1. @命名
  2. 绑定注解

我的问题是,哪个更好?

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

【问题讨论】:

    标签: java dependency-injection guice


    【解决方案1】:

    您通常按照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 将不知道将名称/注释绑定到的女巫类

    【讨论】:

    • Guice 链接提到 Since the compiler can't check the string, we recommend using @Named sparingly. Defining your own purpose-built annotations provides better type-safety. 有人能解释一下它在谈论什么样的类型安全吗?