Guice:绑定具有不同依赖关系的多个对象

Jor*_*orn 5 java guice

我使用Guice绑定有以下代码:

public class MyApplication {
    public static void main(String[] args) {
        Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(Foo.class).annotatedWith(Names.named("first")).toInstance(new Foo("firstFoo"));
                bind(Foo.class).annotatedWith(Names.named("second")).toInstance(new Foo("secondFoo"));

                bind(Bar.class).to(BarImpl.class);

                bind(MyApplication.class).asEagerSingleton();
            }
        });
    }

    private @Named("first") Bar first;
    private @Named("second") Bar second;

    static @Value class Foo { String name; }
    static interface Bar {}

    static class BarImpl implements Bar {
        @Inject @Named Foo foo;
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试为我的应用程序中注入的Bar两个命名Foos 获取一个对象.基本上,它应该以某种方式将@Namedon Foo与on on 连接起来Bar.我尝试了几种解决方案,从@Named一切到写自定义Provider.后者不起作用,因为我无法访问@Named提供程序中的注释值.我认为解决方案就在某个方面bind(Bar.class).to(BarImpl.class);,告诉它要记住@Named注释的价值.

我的问题是,这是否可能,如果是的话,怎么样?

Ale*_*čko 11

它正在使用PrivateModules.基本上:

默认情况下,私有模块的配置信息对其环境是隐藏的.只有明确公开的绑定才可用于其他模块和注入器的用户.有关更多说明,请参阅此FAQ条目.

以下是您如何使用它:

protected void configure() {
    install(new PrivateModule() {
        @Override
        protected void configure() {
            // #bind makes bindings internal to this module unlike using AbstractModule
            // this binding only applies to bindings inside this module
            bind(Foo.class).toInstance(new Foo("first"));
            // Bar's foo dependency will use the preceding binding
            bind(Bar.class).annotatedWith(Names.named("first")).to(BarImpl.class);
            // if we'd stop here, this would be useless
            // but the key method here is #expose
            // it makes a binding visible outside as if we did AbstractModule#bind
            // but the binding that is exposed can use "private" bindings
            // in addition to the inherited bindings              
            expose(Bar.class).annotatedWith(Names.named("first"));
        }
    });
    install(new PrivateModule() {
        @Override
        protected void configure() {
            bind(Foo.class).toInstance(new Foo("second"));
            bind(Bar.class).annotatedWith(Names.named("second")).to(BarImpl.class);
            expose(Bar.class).annotatedWith(Names.named("second"));
        }
    });
         bind(MyApplication.class).asEagerSingleton();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你有效地拥有2个条状,每个条状看起来像

static class BarImpl implements Bar {
    @Inject Foo foo;
}
Run Code Online (Sandbox Code Playgroud)

但是,PrivateModules的强大功能对同一个依赖项有不同的实现约束.

希望它有意义.