java 注入命名 Guice 单例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14781771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:22:31  来源:igfitidea点击:

Injecting named Guice singleton

javadependency-injectionjunitguice

提问by IAmYourFaja

I have a simple POJO:

我有一个简单的 POJO:

public class MyPOJO {
    @Inject
    private Fizz fizz;

    private Buzz buzz;

    // rest of class omitted for brevity
}

I would like to configure my Guice module such that there are two types of Fizzes that it injects:

我想配置我的 Guice 模块,Fizz以便它注入两种类型的es:

  1. A special, globally-singleton Fizzinstance; and
  2. Other (non-special) Fizzinstances
  1. 一个特殊的全局单例Fizz实例;和
  2. 其他(非特殊)Fizz实例

I want MyPOJOto be injected with the special/singleton instance. So I modified my code:

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

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

    private Buzz buzz;

    // rest of class omitted for brevity
}

Then in my module:

然后在我的模块中:

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);
    }
}

But when I try to unit test (JUnit 4.10) this:

但是当我尝试单元测试(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);
    }
}

This passes. So far, so good. But then if I change the name of the specialFizzfield:

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

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

And re-run the test, it still passes. Why?!? Where am I going astray here? Thanks in advance.

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

采纳答案by condit

Very odd. Guice should complain if it can't find a Namedbinding that it's injecting. I'm a bit confused by your test, though. I don't know what injector.injectdoes. Do you mean injectMembers? It might make more sense to actually get an instance of your POJO and make sure that it's working the way you expect. Maybe something like:

很奇怪。如果 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);
  }

}

回答by Bradley T. Hughes

Guice sees the @Providesmethod and happily uses that to inject the Fizz. If you want to have a special instance of Fizz, you can drop the annotations from the providesFizz()method and instead bind with

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

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

This way, you tell Guice exactly which Fizzto use as the "Special-Fizz", while still letting it inject Fizz"normally" otherwise.

通过这种方式,您可以准确地告诉 Guice 将哪个Fizz用作“Special-Fizz”,同时仍然让它Fizz“正常”注入。

Disclaimer: I haven't actually tried a setup like yours, but I have used one similar. Let me know if it works or not.

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