Java 注入命名Guice singleton

Java 注入命名Guice singleton,java,dependency-injection,junit,guice,Java,Dependency Injection,Junit,Guice,我有一个简单的POJO: public class MyPOJO { @Inject private Fizz fizz; private Buzz buzz; // rest of class omitted for brevity } 我想配置我的Guice模块,使其注入两种类型的Fizzes: 一个特殊的全局单例Fizz实例;及 其他(非特殊)Fizz实例 我希望MyPOJO被注入特殊的/singleton实例。所以我修改了我的代码: public c

我有一个简单的POJO:

public class MyPOJO {
    @Inject
    private Fizz fizz;

    private Buzz buzz;

    // rest of class omitted for brevity
}
我想配置我的Guice模块,使其注入两种类型的
Fizz
es:

  • 一个特殊的全局单例
    Fizz
    实例;及
  • 其他(非特殊)
    Fizz
    实例
  • 我希望
    MyPOJO
    被注入特殊的/singleton实例。所以我修改了我的代码:

    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)时,我发现:

    这就过去了。到目前为止,一切顺利。但是如果我更改
    specialFizz
    字段的名称:

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

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

    Guice看到
    @提供了
    方法,并愉快地使用该方法注入
    气泡。如果希望有一个特殊的
    Fizz
    实例,可以从
    providesFizz()
    方法中删除注释,并使用绑定

    bind(Fizz.class)
        .annotatedWith(Names.named("Special-Fizz")
        .toInstance(providesFizz());
    
    这样,您就可以准确地告诉Guice使用哪个
    Fizz
    作为“特殊Fizz”,同时仍然让它“正常”地注入
    Fizz


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

    非常奇怪。如果Guice找不到它正在注入的名为
    的绑定,它应该抱怨。不过,你的测试让我有点困惑。我不知道injector.Injection的功能是什么。你是说
    会员
    ?实际获取POJO的一个实例并确保它按照您期望的方式工作可能更有意义。可能是这样的:

    public-class-FizzTest{
    公共静态类MyModule扩展了AbstractModule{
    @凌驾
    受保护的void configure(){
    }
    @提供
    @独生子女
    @命名为(“特殊汽水”)
    公共Fizz提供Fizz(){
    返回新的气泡(true);
    }
    }
    公共静态类嘶嘶声{
    布尔特殊=假;
    公共汽水(){}
    公共汽水(布尔特殊){
    这个。特别的=特别的;
    }
    }
    公共静态类MyPOJO{
    @注入@Named(“特殊泡沫”)
    私人汽笛;
    @注入
    私人汽水或其他汽水;
    }
    @试验
    公开无效测试(){
    MyModule mod=新的MyModule();
    注入器注入器=Guice.createInjector(mod);
    MyPOJO-pojo=injector.getInstance(MyPOJO.class);
    资产真实(pojo.fizz.special);
    资产真实(!pojo.otherFizz.special);
    }
    }
    
    谢谢@Bradley T.Hughes(+1)-不过你的建议不会改变任何事情。无论您如何命名
    Fizz
    ,单元测试仍然通过。你提到了一些我觉得有趣的事情。您说“我实际上没有尝试过像您这样的设置…”,但是,从您的回答中,我推断您似乎对使用Guice相当满意。所以我想知道:我使用的是一种奇怪的设置吗?我认为Guice的重点是将类和注释一起使用,以精确地确定您想要注入的类型/配置……那么我在这里做的事情是否与众不同?如果是,为什么?!?我在哪里误解了Guice的正常用法?再次感谢!我不认为这是一个奇怪的设置。老实说,我没有太多使用Guice,所以我肯定不是专家。不同之处在于我正在处理的代码使用相同的注释来注入两种不同的类型(每种类型都有一个实例)。谢谢@condit(+1)-这是我在输入这个问题时的一个错误。我编辑了我的原始问题,以表明我实际上在调用
    injector.getInstance
    ,而不是
    injector.injector
    。这对你有什么改变吗?我在这里使用的
    getInstance
    是否不正确?如果是,原因是什么?再次感谢!在您的测试中,您要求喷油器提供一个
    Fizz
    实例,它将始终能够提供给您(因为您的
    @Provides
    方法)。我想您应该获得一个
    MyPOJO
    的实例。请注意,您得到的
    Fizz
    与测试的
    Fizz
    成员无关。因此更改名为
    @在这种情况下不会有任何效果。你搞定了。我刚刚要求它注入一个
    MyPOJO
    ,它正确地用我的特殊Fizz注入了它的
    Fizz
    属性。谜团解决了——只是一个执行不力的测试方法。再次感谢!
    bind(Fizz.class)
        .annotatedWith(Names.named("Special-Fizz")
        .toInstance(providesFizz());