当前位置: 首页 > 面试题库 >

使用Multibinding概括guice的机械手示例

燕嘉颖
2023-03-14
问题内容

我有一个与Guice的机器人腿示例非常相似的用例,除了我不知道我有多少个“腿”。因此,我不能使用机器人腿示例所需的注释。

我希望将所有这些“腿”收集到带有Guice的Multibindings扩展的java.util.Set中。

从技术上讲,在PrivateModule中,我想将实现直接公开为Multibindings扩展所提供的集合的元素。我只是不知道该怎么做。

有关参考和代码示例,请参见此处的机械臂示例:[http]( http://code.google.com/p/google-
guice/wiki/FrequentlyAskedQuestions#How_do_I_build_two_similar_but_slightly_different_trees_of_objec)
//code.google.com/p/google-
guice/wiki/FrequentlyAskedQuestions#How_do_I_build_two_like_but_slightly_different_trees_of_objec

这是我的确切用例:

我有以下内容:

// Main application
public interface MyTree {...}
public interface MyInterface {
  public MyTree getMyTree() {}
}
public abstract class MyModule extends PrivateModule {}
public class MyManager {
  @Inject MyManager (Set<MyInterface> interfaces){ this.interfaces = interfaces }
}
public class MainModule extends AbstractModule {
  public void configure () {
    // Install all MyModules using java.util.ServiceLoader.
  }
}


// In expansion "square.jar"
public class SquareTree implements MyTree {...}
public class SquareImplementation implements MyInterface {
  @Inject SquareImplementation (MyTree tree) { this.tree = tree; }
  public MyTree getMyTree () { return this.tree; }
}
public class SquareModule extends MyModule { // correctly defined as a ServiceLoader's service.
  public void configure () {
    // How to make this public IN a multibinder's set?
    bind(MyInterface.class).to(SquareImplementation.class);

    // Implementation specific to the Squareimplementation.
    bind(MyTree.class).to(SquareTree.class);
  }
}

// In expansion "circle.jar"
public class CircleTree implements MyTree {...}
public class CircleImplementation implements MyInterface {
  @Inject CircleImplementation (MyTree tree) { this.tree = tree; }
  public MyTree getMyTree () { return this.tree; }
}
public class CircleModule extends MyModule { // correctly defined as a ServiceLoader's service.
  public void configure () {
    // How to make this public IN a multibinder's set?
    bind(MyInterface.class).to(CircleImplementation.class);

    // Implementation specific to the Circle implementation.
    bind(MyTree.class).to(CircleTree.class);
  }
}

由于我是在谈论扩展jar,因此我一开始并不了解它们,甚至不知道其中有多少:我需要加载MyModules,j.u.ServiceLoader每个模块都应定义一个MyInterface实现(这两个部分是好)。

问题是将所有MyInterface实现都放在一个集合中(在中MyManager)。我怎样才能做到这一点?

解决方案,完全基于Jesse的回答:

// Create the set binder.
Multibinder<MyInterface> interfaceBinder = Multibinder.newSetBinder(binder(), MyInterface.class, MyBinding.class);

// Load each module that is defined as a service.
for (final MyModule module : ServiceLoader.load(MyModule.class)) {

  // Generate a key with a unique random name, so it doesn't interfere with other bindings.
  final Key<MyInterface> myKey = Key.get(MyInterface.class, Names.named(UUID.randomUUID().toString()));
  install(new PrivateModule() {
    @Override protected void configure() {
      // Install the module as part of a PrivateModule so they have full hands on their own implementation.
      install(module);
      // Bind the unique named key to the binding of MyInterface.
      bind(myKey).to(MyInterface.class);
      // Expose the unique named binding
      expose(myKey);
    }
  });
  // bind the unique named binding to the set
  interfaceBinder.addBinding().to(myKey);
}

这使我不必强迫“客户”扩展PrivateModule,而如果MyModule是扩展Module的接口,则可以使用任何模块实现。


问题答案:

看起来您将需要跳过一些箍,以保证私有模块的绑定状态,以便它们可以在顶级注射器的多重绑定中使用。

这应该工作:

public class SquareModule extends AbstractModule { // does not extend PrivateModule
  @Overide public void configure() {
    // this key is unique; each module needs its own!
    final Key<MyInterface> keyToExpose
        = Key.get(MyInterface.class, Names.named("square"));

    install(new PrivateModule() {
      @Override public void configure() {

        // Your private bindings go here, including the binding for MyInterface.
        // You can install other modules here as well!
        ...

        // expose the MyInterface binding with the unique key
        bind(keyToExpose).to(MyInterface.class);
        expose(keyToExpose);
      }
    });

    // add the exposed unique key to the multibinding
    Multibinder.newSetBinder(binder(), MyInterface.class).addBinding().to(keyToExpose);
  }
}

此解决方法是必需的,因为需要在顶级进样器处进行多重绑定。但是专用模块绑定对该注入器不可见,因此您需要公开它们。



 类似资料:
  • 问题内容: 我想知道是否有类似Java的Perl / Python机械化的东西。 谢谢! 问题答案: 看看HtmlUnit。它类似于Perl的WWW :: Mechanize 。还有一个Perl版本,名为WWW :: HtmlUnit (它使用Inline :: Java 将Java库的方法公开给Perl)。

  • 我尝试连接到一个SPNEGO安全的网站与curl(在Mac OS X 10.10与运送curl) 问题似乎是“gss_init_sec_context()失败::未知机械代码0表示机械未知”。curl看起来像是用SPNEGO/GSS正确编译的? 编辑:HTTPie(https://github.com/ndzou/httpie-negotiate)显示类似的行为。它在第一个服务器响应之后停止。服务

  • CC视频支持用户使用手机APP发起直播,手机直播支持iOS、安卓和微信小程序。在直播发起前需要进行以下准备工作: 手机环境要求 操作系统:Android 4.3以上,iOS 9.0以上 网络带宽:上行带宽达到2Mbps以上,建议使用Wi-Fi网络 推流客户端安装 点击客户端安装包进行安装,安装过程中如提示开启相应权限请选择“开启”。安装完成后点击程序图标即可启动客户端。 iOS端APP下载 扫描二

  • 电商数据服务接口面向所有开发伙伴,提供各类电商数据原材料接口,获取品类、品牌、平台及单品销售额、销售量、行业平均成交价等数据,从而让开发者自行封装各类产品服务。我们的愿景是通过深入合作与共同探寻,为广大开发者提供丰富的数据来源,实现业务的深度对接,共同打造良好的开放共赢生态体系。 优势: 数据来源覆盖主流电商平台,最大程度上获取品牌相对完整的线上数据表现。 API涵盖品牌核心交易数据,从品类销售额

  • 现在我们已经学习了很多详细的内容,我们可以开始学习更加令你感兴趣的东西,比如控制流语句。在继续学习之前,请确信你对本章的内容清楚明了。

  • 问题内容: 因此,我对网络抓取还很陌生。该站点上有一个表,该表的值由Javascript控制。这些值将确定告诉我的浏览器从Javascript请求的将来值的地址。这些新页面具有JSON响应,脚本会使用该JSON更新浏览器中的表。 因此,我想用一个机械化的方法来构建一个类,该方法接受一个url并吐出主体响应,而对于HTML而言,这是第一次,对于其余的迭代,主体响应将为JSON。 我有一些有效的方法,