5

我有一个简单的 POJO:

public class MyPOJO {
    @Inject
    private Fizz fizz;

    private Buzz buzz;

    // rest of class omitted for brevity
}

我想配置我的 Guice 模块Fizz,使其注入两种类型的 es:

  1. 一个特殊的全局单例Fizz实例;和
  2. 其他(非特殊)Fizz实例

我想MyPOJO注入特殊/单例实例。所以我修改了我的代码:

public class MyPOJO {
    @Inject @Named("Special-Fizz")
    private Fizz fizz;

    private Buzz buzz;

    // rest of class omitted for brevity
}

然后在我的模块中:

public class MyModule extends AbstractModule {
    @Override
    public void configure() {
        bind(Fizz.class).annotatedWith(
            Names.named("Special-Fizz"))
            .to(Fizz.class);

        // Other bindings here...
    }

    @Provides @Singleton
    private Fizz providesFizz() {
        return new Fizz(true, "Special", 12.0);
    }
}

但是当我尝试单元测试(JUnit 4.10)时:

public class MyTest {
    @Named("Special-Fizz") private Fizz specialFizz;

    @Test
    public void usingNamedShouldInjectSpecialFizz() {
        MyModule mod = new MyModule();
        Injector injector = Guice.createInjector(mod);

        specialFizz = injector.getInstance(Fizz.class);

        Assert.assertTrue(specialFizz != null);
    }
}

这通过了。到现在为止还挺好。但是,如果我更改该specialFizz字段的名称:

    @Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz;

并重新运行测试,它仍然通过。为什么?!?我在哪里会误入歧途?提前致谢。

4

2 回答 2

5

很奇怪。如果 Guice 找不到Named它正在注入的绑定,它应该抱怨。不过,我对你的测试有点困惑。我不知道有什么injector.inject作用。你的意思是injectMembers?实际获取 POJO 的实例并确保它以您期望的方式工作可能更有意义。也许是这样的:

public class FizzTest {

  public static class MyModule extends AbstractModule {
    @Override
    protected void configure() {
    }

    @Provides
    @Singleton
    @Named("Special-Fizz")
    public Fizz providesFizz() {
      return new Fizz(true);
    }
  }

  public static class Fizz {
    boolean special = false;
    public Fizz() {}
    public Fizz(boolean special) {
      this.special = special;
    }
  }

  public static class MyPOJO {
    @Inject @Named("Special-Fizz")
    private Fizz fizz;

    @Inject
    private Fizz otherFizz;
  }

  @Test
  public void test() {
    MyModule mod = new MyModule();
    Injector injector = Guice.createInjector(mod);

    MyPOJO pojo = injector.getInstance(MyPOJO.class);
    assertTrue(pojo.fizz.special);
    assertTrue(!pojo.otherFizz.special);
  }

}
于 2013-02-09T01:44:25.533 回答
2

Guice 看到了这个@Provides方法,并愉快地使用它来注入Fizz. 如果你想有一个特殊的实例Fizz,你可以从方法中删除注释providesFizz(),而是绑定

bind(Fizz.class)
    .annotatedWith(Names.named("Special-Fizz")
    .toInstance(providesFizz());

通过这种方式,您可以准确地告诉 GuiceFizz使用哪个作为“Special-Fizz”,否则仍然让它Fizz“正常”注入。

免责声明:我实际上没有尝试过像您这样的设置,但我使用过类似的设置。让我知道它是否有效。

于 2013-02-08T21:58:39.900 回答