java - 如何配置 Guice,使其注入(inject)到我想要的绑定(bind)类中?

标签 java guice

我有以下情况:

public class User {

@Inject
private MusicInterface movie;

}

public interface MusicInterface {
public void getTitle();
}

并且有 Guice 配置类:

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

我的问题是: 如何将我想要的音乐绑定(bind)注入(inject)到用户类中?

例如:

在我的 main 中,我想获得带有名为 rock 的注入(inject)类的 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。

我该怎么做?

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

最佳答案

听起来您想要做的是根据用户的注释绑定(bind)不同种类的音乐。这也称为 the Robot Legs problem ,除非您可以将“腿”替换为“用户”,将“脚”替换为“音乐”。这可以使用 Private Modules 来实现。在 Guice 中,但您可能会发现创建 UserFactory 更容易。我将向您展示两种方法。

首先,Private Module方式。私有(private)模块向外界隐藏所有绑定(bind),因此您可以公开某些模块而不会与其他模块发生冲突。

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

现在您可以请求 @Named("user1") User获得喜欢摇滚音乐的用户。当然,您不必像我使用该方法那样组织它:如果您愿意,您仍然可以将 MusicInterface 的类型绑定(bind)到名称,然后将无注释的 MusicInterface 绑定(bind)到 Key.get(MusicInterface.class, yourMusicTypeHere)在您的 PrivateModule 中,但除非您在其他地方需要指定的 MusicInterfaces,否则您可以跳过该步骤。

另一种方法是跳过使用 Guice 进行此绑定(bind)。 Guice 是一个很好的解决方案,但对于一些复杂的绑定(bind)情况,设置起来可能会比较麻烦。您的替代方案是创建一个轻量级 UserFactory 来为您选择正确的音乐类型。 ( ImmutableMap 来自 Guava 。)

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

现在您的用户将可以通过注入(inject) UserFactory 来使用并调用userFactory.create() 。当然,也许您的用户需要十几个其他注入(inject)的依赖项。在这种情况下,第一个选项看起来不错,或者您可以调查 assisted injection 。所有这些都是可行的选项,因此您需要考虑哪一个是适合您的情况的灵 active 和可读性的正确组合。

希望有帮助!

关于java - 如何配置 Guice,使其注入(inject)到我想要的绑定(bind)类中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13807747/

相关文章:

java - 尝试使用用户输入创建矩阵时出现编译错误。 java

java - java中有没有时间跟踪/监控框架

android - 在 Android 中使用 GWT 源代码

java - Google Appengine 上的 Google Guice : mapping with working _ah

java - 如何使用 Google Guice 创建需要参数的对象?

java - 是否可以为模块注入(inject)值(value)

java - 为正则表达式生成所有有效值

java - 如何用java提取字符串中的特定字母

Java EE 身份验证 : how to capture login event?

android - Roboguice @Inject 服务困惑