为了账号安全,请及时绑定邮箱和手机立即绑定

使用注释为 Google guice MapBinder 提供数据

使用注释为 Google guice MapBinder 提供数据

慕哥9229398 2022-07-14 10:18:31
在 Java 项目中,使用 Gradle 5.2 和 Google Guice 进行构建。我使用MapBinder(http://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/multibindings/MapBinder.html):MapBinder<String, Snack> mapbinder         = MapBinder.newMapBinder(binder(), String.class, Snack.class);     mapbinder.addBinding("twix").toInstance(new Twix());     mapbinder.addBinding("snickers").toProvider(SnickersProvider.class);     mapbinder.addBinding("skittles").to(Skittles.class);这工作正常,但现在,我想要一个“插件架构”,所以避免导入所有 Snack 类,而是直接在类中声明它,例如:@SnackImpl("Twix")class Twix extends Snack {}如何?
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

如果没有一些昂贵的类路径扫描,这将是不可能的:如果注入器没有对您的 Twix 类的任何引用,它就无法在不扫描类路径上的每个 JAR 的情况下将其绑定到 Map 中@SnackImpl-带注释的类。您可以尝试使用Guava 的 ClassPath,但如果您使用基于网络或自定义的类加载器,这可能根本无法处理。无论如何,我不会推荐它。


一种替代方法是使用 Java 的内置ServiceLoader框架,该框架允许各个 JAR 列出给定服务(接口)的完全合格的实现。您甚至可以使用 Google 的 Auto 框架根据注释为您生成该服务文件。


这需要列出实现,但您仍然需要将它们绑定到 MapBinder。幸运的是,MapBinder 不需要单个定义,并且会在模块构建期间自动合并多个 MapBinder 定义:


支持从不同模块贡献映射绑定。例如,可以让 CandyModule 和 ChipsModule 都创建自己的 MapBinder,并各自为小吃地图提供绑定。注入该映射后,它将包含来自两个模块的条目。


(来自MapBinder 文档)


考虑到这一点,我建议每个插件包都有自己的 Guice 模块,并在其中注册到 MapBinder,然后使用 ServiceLoader 将这些 Guice 模块添加到主注入器,以便在注入器创建时获取这些模块。


// Assume CandyPluginModule extends AbstractModule


@AutoService(CandyPluginModule.class)

public TwixPluginModule extends CandyPluginModule {

  @Override public void configure() {

    MapBinder<String, Snack> mapBinder

       = MapBinder.newMapBinder(binder(), String.class, Snack.class);

    mapBinder.addBinding("twix").to(Twix.class);

  }

}

您还可以利用超类:


@AutoService(CandyPluginModule.class)

public TwixPluginModule extends CandyPluginModule {

  @Override public void configureSnacks() {  // defined on CandyPluginModule

    bindSnack("twix").to(Twix.class);

  }

}

或者,您可以直接使用 AutoService 列出 Twix 之类的实现,然后创建一个模块,将所有 ServiceLoader 实现读入您的 MapBinder,但这可能会限制您的插件的灵活性,并且不会让您获得 MapBinder 没有的绑定的任何分散化还没给你。


查看完整回答
反对 回复 2022-07-14
  • 1 回答
  • 0 关注
  • 73 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信