Java 如何配置Guice,将其注入到我想要的绑定类中?

Java 如何配置Guice,将其注入到我想要的绑定类中?,java,guice,Java,Guice,我有以下情况: public class User { @Inject private MusicInterface movie; } public interface MusicInterface { public void getTitle(); } 并具有GUI配置类: public class Module extends AbstractModule { @Override protected void configure() { bind(

我有以下情况:

public class User {

@Inject
private MusicInterface movie;

}

public interface MusicInterface {
public void getTitle();
}
并具有GUI配置类:

public class Module extends AbstractModule {

    @Override
    protected void configure() {

        bind(MusicInterface.class).annotatedWith(Names.named("rock")).to(RockMusic.class);
        bind(MusicInterface.class).annotatedWith(Names.named("pop")).to(PopMusic.class);
        bind(User.class).annotatedWith(Names.named("user1").to(User.class);
        bind(User.class).annotatedWith(Names.named("user2").to(User.class);
    }
}
我的问题是: 如何将我想要的音乐绑定注入用户类

例如:

在我的主要内容中,我想使用名为rock的注入类获取User1:

Injector injector = Guice.createInjector(new Module());

User user1 = injector.getInstance(Key.get(User.class,Names.named("user1")));
假设user1具有RockMusic.class属性,稍后我想使用流行音乐获取user2:

User user2 = injector.getInstance(Key.get(User.class,Names.named("user2")));
这个类将具有属性PopMusic.class

我该怎么做


我知道我可以在用户类中使用注释@Named(…),但在我的情况下这不是一个解决方案。

鉴于@Named不是一个选项,我想您也不能使用绑定注释。您可以向喷油器索取:

Injector injector = Guice.createInjector(new Module());
MusicInterface musicInterface = injector.getInstance(Key.get(String.class, Names.named("rock"))

听起来你想做的是根据用户的注释绑定不同种类的音乐。这也被称为,除了你可以用“用户”替换“腿”,用“音乐”替换“脚”。这可以在Guice中使用,但您可能会发现创建UserFactory更容易。我会告诉你两种方法

首先,这条路。私有模块对外隐藏所有绑定,因此您可以公开某些绑定,而不会与其他绑定发生冲突

public class MyModule extends AbstractModule {
  @Override protected void configure() {
    install(privateModuleFor("user1", RockMusic.class));
    install(privateModuleFor("user2", PopMusic.class));
  }

  private static Module privateModuleFor(
      final String userName, final Class<? extends MusicInterface> musicClass) {
    return new PrivateModule() {
      @Override protected void configure() {
        // Bind the annotated user.
        bind(User.class).annotatedWith(Names.named(userName)).to(User.class);
        // Now bind the music class as if it's the only music class ever.
        bind(MusicInterface.class).to(musicClass);
        // The above two bindings are hidden, and available only in this module,
        // so Guice doesn't complain about two different competing
        // MusicInterfaces. In order to get access to the User binding
        // outside the module, expose it.
        expose(User.class).annotatedWith(Names.named(userName));
      }
    };
  }
}
现在您的用户可以通过注入
UserFactory
并调用
UserFactory.create()。当然,您的用户可能还需要一打其他注入依赖项。在这种情况下,第一个选项看起来不错,或者您可以进行调查。所有这些都是可行的选择,因此您需要考虑哪一个是适合您的情况的灵活性和可读性的正确组合


希望有帮助

什么表达了您的“想要”绑定是什么?为什么一个用户会得到摇滚音乐和另一个流行音乐?我仍然很困惑,因为我不知道如何做到这一点:user user1=injector.getInstance(Key.get(user.class,Names.named(“user1”));User user2=injector.getInstance(Key.get(User.class,Names.named(“user2”));同一个类如何命名两次?你考虑过用泛型来代替吗?类似User User=injector.getInstance(Key.get(new-TypeLiteral(){}))@Eiv的东西很高兴能帮上忙!一旦你感到满意,请记住将你个人最有用的答案标记为已接受(用复选标记)。
public class UserFactory {
  private Map<String, Class<? extends MusicInterface>> musicMap =
      ImmutableMap.builder()
        .put("user1", RockMusic.class)    // You could also put instances here
        .put("user2", PopMusic.class)     // and skip using Guice entirely!
        .build();

  // Never inject Injector unless you don't know what you need until runtime,
  // which is exactly what is happening here.
  @Inject private Injector injector;
  @Inject private Provider<Dependency> someOtherUserDependency;

  public User createUser(String musicType) {
    Class<? extends MusicInterface> clazz = musicMap.get(musicType);
    return new User(injector.getInstance(clazz), someOtherUserDependency.get());
  }
}