在使用Guice's MapBinder
使用Guice 3.0构建插件架构的过程中,我遇到了Guice在剥离所有模块时抛出CreationException
的问题,这是一个该应用程序中的可行配置。有没有办法让Guice注入空Map
?或者,通过扩展名,使用Multibinder
?
例如:
interface PlugIn {
void doStuff();
}
class PlugInRegistry {
@Inject
public PlugInRegistry(Map<String, PlugIn> plugins) {
// Guice throws an exception if OptionalPlugIn is missing
}
}
class OptionalPlugIn implements PlugIn {
public void doStuff() {
// do optional stuff
}
}
class OptionalModule extends AbstractModule {
public void configure() {
MapBinder<String, PlugIn> mapbinder =
MapBinder.newMapBinder(binder(), String.class, PlugIn.class);
mapbinder.addBinding("Optional").to(OptionalPlugIn.class);
}
}
答案 0 :(得分:3)
在MapBinder的文档中,它说:
支持从不同模块贡献地图绑定。例如,可以让CandyModule和ChipsModule都创建自己的MapBinder,并为每个提供绑定到小吃地图。注入该映射时,它将包含来自两个模块的条目。
所以,你要做的就是,不要在基本模块中添加条目。做这样的事情:
private final class DefaultModule extends AbstractModule {
protected void configure() {
bind(PlugInRegistry.class);
MapBinder.newMapBinder(binder(), String.class, PlugIn.class);
// Nothing else here
}
}
interface PlugIn {
void doStuff();
}
然后,当您创建注射器时,如果存在其他模块,那太好了!添加它们。如果它们不存在,那么就不要添加它们。在你的班上,这样做:
class PlugInRegistry {
@Inject
public PlugInRegistry(Map<String, PlugIn> plugins) {
PlugIn optional = plugins.get("Optional");
if(optional == null) {
// do what you're supposed to do if the plugin doesn't exist
}
}
}
注意:如果没有可选模块,您必须使用空的MapBinder
,否则Map
注入将无效。