【问题标题】:How to implement command pattern via CDI?如何通过 CDI 实现命令模式?
【发布时间】:2013-12-07 18:38:30
【问题描述】:

我是 CDI 的新手,有点困惑。我有以下问题。我们有集体行动。我们有一个包装类,它将所有 Action 对象保存在 hashmap 中。像这样。

class TestAction implements Action{
  @EJB
  private MyBean bean; 
  public void doSomething(){
    //here we do something with injected EJB
  }
}

class Foo {
   private HashMap<String, Action> hm;
   public void execute (String action){
   this.hm.get(action).doSomething();    
 }    
}

当我不使用 CDI 时 - 一切正常。但我需要使用它。因此,据我了解,我必须通过 cdi 容器创建所有操作,否则 CDI 容器无法将托管 bean 注入其中。所以我的问题是通过 CDI 实现命令模式的最佳方法是什么?

已编辑: 我阅读了 Dhanji R. Prasanna 的 Dependency Injection,Weld-reference(WR),JavaEE7 教程(CDI 部分)——不建议阅读最后一篇。稍微思考了一下,我明白我需要注入 HashMap。此外,我明白我必须使用生产者方法。好的。我说。最后我明白了。于是我写了如下生产者方法:

@ApplicationScoped
public class ActionMapFactory {
    @Produces @Preffered
    public HashMap<String, Action> getHashMap(){
    HashMap<String, Action> hm=new HashMap<>();
     if (...){
     hm.put("save",new SaveAction());
     }
     return hm;
    }
}

来自 WR:

上面的代码存在一个潜在问题。实施 of 使用 Java new 运算符实例化。对象 由应用程序直接实例化不能利用 依赖注入并且没有拦截器。

我已经阅读了 WR 的解决方案,但是如果我有几十个动作和很多 Foo 的子类,我该怎么办?

【问题讨论】:

    标签: java jakarta-ee design-patterns dependency-injection


    【解决方案1】:

    您可以通过将所有操作注入ActionMapFactory 并在生产者方法中填充HashMap 来避免new

    @ApplicationScoped
    public class ActionMapFactory {
    
        @Inject
        private SaveAction saveAction;
    
        @Inject
        private DeleteAction deleteAction;
    
        // And so on
    
        @Produces @Preffered
        public HashMap<String, Action> getHashMap() {
            Map<String, Action> hm = new HashMap<>();
            hm.put("save", saveAction);
            hm.put("delete", deleteAction);
            return hm;
        }
    }
    

    如果您不想将这些 Action 实例保留为属性,请执行构造函数注入:

    private Map<String, Action> actionMap;
    
    // This is part of the CDI bean contract
    protected ActionMapFactory() {}
    
    @Inject
    public ActionMapFactory(SaveAction saveAction, DeleteAction deleteAction) {
        actionMap = new HashMap<>();
        actionMap.put("save", saveAction);
        actionMap.put("delete", deleteAction);
    }
    
    @Produces @Preffered
    public HashMap<String, Action> getHashMap() {
        return actionMap;
    }
    

    【讨论】:

    • 其实我现在做的是构造函数注入。但是手动编写所有操作并不是很好。使用命令模式,我们可以自动创建 actionMap。那就是我们只是在包中创建类,仅此而已。
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    相关资源
    最近更新 更多