2013-03-08 25 views
5

biegnę do problemu z CDI wstrzyknięcie do kontenera Weld w JBoss 7.1.1CDI pętla wtrysk

Mam następujący model obiektu:

@Stateless 
class ServiceEjb { 
@Inject 
A a; 
} 

class A { 
@Inject 
B b; 
} 

class B { 
@Inject 
A a; 
} 

Gdy próbuje wstrzyknąć lub B w mojej klasie bezstanowej, pętla wtryskowa i awaria z wyjątkiem javax.enterprise.inject.CreationException.

Próbuję wielu rzeczy (scoping, @Singleton na A lub B, ale bez powodzenia). Nie chcę łamać kodu, a te zastrzyki tworzą zmysły.

Wszelkie wskazówki będą mile widziane.

Odpowiedz

10

Circular dependency injection is not required by the CDI standard, chyba że co najmniej jedna fasola w cyklu ma normal scope. Najprostszym rozwiązaniem jest nadanie A lub B normalnego zakresu. Jeśli nie możesz podać normalnego zakresu (z makiety kodu, wygląda na to, że wszystkie mają domyślny pseudo zakres), będziesz musiał poszukać innych rozwiązań. Opublikowanie prawdziwego kodu źródłowego może nam pomóc w znalezieniu konkretnego rozwiązania, ale tutaj jest początek:

  • Czy A i B można połączyć w jedną klasę?
  • Czy nowa klasa, C, może być wyodrębniona z A i B, tak że zamiast A i B @Inject C zamiast siebie?

Oto niektóre SO powiązania z innymi rozwiązaniami, które mogą Ci się przydać:

MVP with CDI; avoiding circular dependency

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

+0

Dziękuję za szybką odpowiedź. Muszę przyznać, że pojęcie normalnego zakresu nie jest dla mnie jasne. Łącza, które podasz, mówią o @NormalScope, ale to nie istnieje. Jak zadeklarować normalny zakres? – jmcollin92

+0

[Większość zakresów to normalne zakresy.] (Http://docs.jboss.org/cdi/spec/1.0/html/contexts.html#normalscope) Zakresy sesji, aplikacji, rozmowy i żądania to normalne zakresy. Jest to sprzeczne z _pseudoskopy_: singleton i zależne (co jest domyślne, gdy nie piszesz w adnotacji zakresu). – Nick

+0

Tak więc, ponieważ już próbuję zadeklarować zakres, powinno to działać, jeśli dobrze rozumiem. Jakiego zakresu mogę spróbować do DAO (dostęp przez SessionBean)? – jmcollin92

4

I rozwiązać problem za pomocą javax.inject.Provider wyraźnie. Chociaż mam wrażenie, że to powinno być robione pod maską przez WELD automatycznie, to nie było również w przypadku mnie. To zadziałało dla mnie i rozwiązało mój pokrewny problem.

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

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

nie testowałem, ale może to być wystarczy użyć jednego dostawcy do przerwania cyklu, czyli nie trzeba go używać w obu klasach.

1

Należy wstrzyknąć instancją <B> zamiast B (i/lub wystąpienie < > zamiast)