如何通过CDI实现命令模式?

我是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 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 getHashMap(){ HashMap hm=new HashMap(); if (...){ hm.put("save",new SaveAction()); } return hm; } } 

来自WR:

上面的代码存在一个潜在的问题。 使用Java new运算符实例化实现。 由应用程序直接实例化的对象无法利用dependency injection,也没有拦截器。

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

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

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

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

 private Map 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 getHashMap() { return actionMap; }