Java Guice中的空Multibinder/MapBinder

Java Guice中的空Multibinder/MapBinder,java,plugins,dependency-injection,guice,Java,Plugins,Dependency Injection,Guice,在使用构建插件体系结构的过程中,我遇到了这样一个问题:当去掉所有模块时,Guice抛出了一个CreationException,这在这个应用程序中是一个可行的配置。有没有办法让Guice注入一个空的映射?或者,通过扩展,使用Multibinder 例如: interface PlugIn { void doStuff(); } class PlugInRegistry { @Inject public PlugInRegistry(Map<String, Plug

在使用构建插件体系结构的过程中,我遇到了这样一个问题:当去掉所有模块时,Guice抛出了一个
CreationException
,这在这个应用程序中是一个可行的配置。有没有办法让Guice注入一个空的
映射
?或者,通过扩展,使用
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);
    }
}
接口插件{
void doStuff();
}
类插件注册{
@注入
公共插件注册(映射插件){
//如果缺少OptionalPlugIn,Guice将引发异常
}
}
类OptionalPlugIn实现插件{
公共空间{
//做一些可选的事情
}
}
类OptionalModule扩展了AbstractModule{
public void configure(){
MapBinder MapBinder=
newMapBinder(binder(),String.class,PlugIn.class);
将mapbinder.addBinding(“可选”)添加到(OptionalPlugIn.class);
}
}

在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
    }
  }
}
类插件注册{
@注入
公共插件注册(映射插件){
PlugIn optional=plugins.get(“可选”);
if(可选==null){
//如果插件不存在,请执行您应该执行的操作
}
}
}

注意:您必须使用空的
MapBinder
,否则如果没有可选模块,则
Map
注入将无法工作。

文档中的语言相当晦涩。MapBinder#newMapBinder的文档暗示它纯粹是一种工厂方法,并且不表示任何副作用,例如绑定映射的构造。@是的,文档不是很好。你可以说“有了这个绑定,现在可以注入
Map
”这句话就意味着它。老实说,直到我在自己的系统上做了一个测试用例,我才知道这到底是怎么回事。我的第一次尝试(没有
DefaultModule
empty绑定)失败了,然后我尝试了这个,它成功了。我还碰巧知道,由于我