Guice中是否存在适配Guava Table的MapBinder等效绑定实现?
Guice中Guava Table的绑定方案
Guice官方没有提供和MapBinder对等的原生TableBinder工具,目前常用的有两种落地实现方案:
- 方案1:自定义封装TableBinder(适合需要动态扩展绑定的场景)
核心思路是先通过Multibinder注册所有行、列、值的绑定关系,再通过Provider自动组装为Guava Table实例,参考实现代码如下:
// 定义存储三元组绑定关系的辅助类 public static class TableBinding<R, C, V> { private final R rowKey; private final C columnKey; private final Class<? extends V> valueImpl; public TableBinding(R rowKey, C columnKey, Class<? extends V> valueImpl) { this.rowKey = rowKey; this.columnKey = columnKey; this.valueImpl = valueImpl; } // getter方法省略 } // 在Guice模块中注册所有绑定关系 Multibinder<TableBinding<String, String, Service>> tableBindingSet = Multibinder.newSetBinder( binder(), new TypeLiteral<TableBinding<String, String, Service>>() {} ); tableBindingSet.addBinding().toInstance(new TableBinding<>("row1", "col1", ServiceImpl1.class)); tableBindingSet.addBinding().toInstance(new TableBinding<>("row1", "col2", ServiceImpl2.class)); tableBindingSet.addBinding().toInstance(new TableBinding<>("row2", "col1", ServiceImpl3.class)); // 绑定Table的Provider,自动完成实例组装 bind(new TypeLiteral<Table<String, String, Service>>() {}).toProvider(new Provider<Table<String, String, Service>>() { @Inject private Set<TableBinding<String, String, Service>> bindingSet; @Inject private Injector injector; @Override public Table<String, String, Service> get() { Table<String, String, Service> resultTable = HashBasedTable.create(); for (TableBinding<String, String, Service> binding : bindingSet) { resultTable.put( binding.getRowKey(), binding.getColumnKey(), injector.getInstance(binding.getValueImpl()) ); } return resultTable; } });
- 方案2:直接绑定静态Table实例(适合配置固定的场景)
如果你的Table内容不需要动态扩展,可以直接手动构造实例后绑定,代码更简洁:
Table<String, String, Service> staticTable = HashBasedTable.create(); staticTable.put("row1", "col1", new ServiceImpl1()); staticTable.put("row1", "col2", new ServiceImpl2()); staticTable.put("row2", "col1", new ServiceImpl3()); bind(new TypeLiteral<Table<String, String, Service>>() {}).toInstance(staticTable);
补充说明:如果需要支持按行+列键单独注入对应值,也可以配合Key类加命名注解的方式单独绑定,比如bind(Key.get(Service.class, Names.named("row1:col1"))).to(ServiceImpl1.class),不过这种方式维护成本较高,适合简单场景使用。
内容的提问来源于stack exchange,提问作者chepukha
相关产品推荐
相关产品推荐

