我是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的依赖注入,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:
上面的代码有一个潜在的问题。实施 使用Java new运算符实例化。对象 由应用程序直接实例化无法利用 依赖注入,没有拦截器。
我已经阅读了WR的解决方案,但是如果我有很多动作和很多Foo的子类,我该怎么办?
答案 0 :(得分:1)
您可以通过将所有操作注入new
并在生产者方法中填充ActionMapFactory
来避免HashMap
:
@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;
}