5

Я бегу в вопрос с КДИ инъекций в контейнер Weld в JBoss 7.1.1CDI цикл впрыска

Я получил следующую объектную модель:

@Stateless 
class ServiceEjb { 
@Inject 
A a; 
} 

class A { 
@Inject 
B b; 
} 

class B { 
@Inject 
A a; 
} 

При попытке придать или B в моем классе без гражданства, цикл впрыска и сбой с javax.enterprise.inject.CreationException.

Я пробую много вещей (обзор, @ Синглтон на A или B, но без успеха). Я не хочу нарушать код, и эти инъекции делают чувства.

Любые подсказки будут очень признательны.

ответ

10

Circular dependency injection is not required by the CDI standard, если хотя бы один компонент в цикле имеет normal scope. Самое простое решение - дать A или B нормальный объем. Если вы не можете дать обычный объем (из макета кода, похоже, что у всех их есть псевдо-область по умолчанию @Dependent), вам придется искать другие решения. Проводка реального образца кода может помочь нам с конкретным решением, но вот начало:

  • Может ли A и B быть объединены в один класс?
  • Можно ли извлечь новый класс C из A и B, чтобы оба A и B @Inject C вместо друг друга?

Вот некоторые SO связи с другими решениями, которые могут оказаться полезными:

MVP with CDI; avoiding circular dependency

https://stackoverflow.com/questions/14044538/how-to-avoid-cdi-circular-dependency

+0

Спасибо за быстрый ответ. Я должен признать, что концепция нормального масштаба для меня не очень понятна. Ссылки, которые вы предоставляете, говорят о @NormalScope, но этого не существует. Как объявить нормальный объем? – jmcollin92

+0

[Большинство областей являются нормальными областями.] (Http://docs.jboss.org/cdi/spec/1.0/html/contexts.html#normalscope) Области сеанса, приложения, разговора и запроса являются нормальными областями. Это контрастирует с _pseudoscopes_: singleton и dependency (это значение по умолчанию, когда вы не пишете в аннотации области). – Nick

+0

Итак, поскольку я уже пытаюсь объявить область, это должно работать, если я хорошо понимаю. Какую сферу я могу попробовать в DAO (доступ к SessionBean)? – jmcollin92

4

Я решил проблему с помощью javax.inject.Provider явно. Хотя я чувствую, что это должно быть сделано под капотом WELD автоматически, это не было для меня тоже. Это сработало для меня и решило мою связанную проблему.

class A { 
    @Inject 
    Provider<B> b; // access with b.get() 
} 

class B { 
    @Inject 
    Provider<A> a; // access with a.get() 
} 

Я не проверял, но это может быть достаточно, чтобы использовать один провайдер, чтобы разорвать порочный круг, то есть вам не нужно использовать его в обоих классах.

1

Вы должны вводить в Instance < В > вместо В (и/или Instance < > вместо А)

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