Guice如何根据String id提供不同的子类实例

时间:2011-09-13 16:54:15

标签: java guice

我有一个工厂类用例我想用Guice实现,但不确定如何。 我有一个名为Action的抽象类,它表示用户可以在我的应用上执行的不同类型的操作。 每个Actions都是Action类的子类,每个Actions都有一个String类型的标识。 因为动作是重物,所以我不想让它一下子全部实现,所以我提供了一个工厂来根据客户要求的ID来实现它们。

工厂界面如下所示:

public interface ActionFactory {

    Action getActionByID(String id);

}

我们对这个Factory的实现使用HashMap来维护String实例和一个所谓的ActionInstantiator之间的关系,它将提供具体的Action实例。 这样做的实现如下:

public class ActionFactoryImpl implements ActionFactory {
    private HashMap<String, ActionInstantiator> actions;

    private static ActionFactoryImpl instance;

    protected ActionFactoryImpl(){
       this.actions=new HashMap<String, ActionInstantiator>();
       this.buildActionRelationships();
    }

    public static ActionFactoryImpl instance(){
       if(instance==null)
            instance=new ActionFactoryImpl();
       return instance;
    }

    public Action getActionByID(String id){
        ActionInstantiator ai = this.actions.get(id);
        if (ai == null) {
            String errMessage="Error. No action with the given ID:"+id;
            MessageBox.alert("Error", errMessage, null);
            throw new RuntimeException(errMessage);
        }
        return ai.getAction();
    }

    protected void buildActionRelationships(){
        this.actions.put("actionAAA",new ActionAAAInstantiator());
        this.actions.put("actionBBB",new ActionBBBInstantiator());
        .....
        .....
    }
}

所以一些可以使用这个工厂并想要ActionAAA实例类的客户端就像这样调用它:

Action action=ActionFactoryImpl.instance().getActionByID(actionId);

在运行时从数据库获取 actionId

我发现某种注释注入可以做类似的事情,但在我的情况下我认为这不起作用,因为我只知道用户在运行时需要的实例,所以我无法注释代码。

我是Guice的新手,所以也许这是我在文档中找不到的非常常见的东西,如果是这样的话,那我就是这样的。 任何帮助将不胜感激。 问候 丹尼尔

1 个答案:

答案 0 :(得分:4)

您想要使用Multibindings扩展程序,特别是MapBinder。您可能希望ActionInstantiator类型实现Provider<Action>。然后你可以这样做:

MapBinder<String, Action> mapbinder
     = MapBinder.newMapBinder(binder(), String.class, Action.class);
mapbinder.addBinding("actionAAA", ActionAAAInstantiator.class);
// ...

然后你可以在你需要的地方注入Map<String, Provider<Action>>。您还可以将内容注入ActionInstantiator