2013-11-22 5 views
3

Я новичок в CDI и немного смущен. У меня есть следующая проблема. У нас есть класс Action. И у нас есть класс-оболочка, который сохраняет все объекты Action в hashmap. Что-то вроде этого.Как реализовать командный шаблон через CDI?

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 не сможет вводить в него управляемые компоненты. Итак, мой вопрос: какой лучший способ реализовать командный шаблон через CDI?

Редакция: Я прочитал Dependency Injection по Dhanji Р. Prasanna, Weld-ссылка (WR), JavaEE7 учебник (КДИТЕ часть) - не рекомендую прочитать последний. Подумав немного, я понял, что мне нужно ввести 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?

ответ

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; 
} 
+0

Фактически я делаю теперь как инъекцию конструктора. Но не очень приятно писать вручную все действия. Используя шаблоны команд, мы могли бы создать actionMap автоматически. То есть мы просто создаем класс в пакете, и все. –

Смежные вопросы