2013-03-08 14 views
5

Io corro in un problema con il CDI iniezione in un contenitore di saldatura in JBoss 7.1.1CDI ciclo di iniezione

Ho il seguente modello oggetto:

@Stateless 
class ServiceEjb { 
@Inject 
A a; 
} 

class A { 
@Inject 
B b; 
} 

class B { 
@Inject 
A a; 
} 

Quando si tenta di iniettare una o B nella mia classe stateless, ciclo di iniezione e arresto anomalo con javax.enterprise.inject.CreationException.

Provo molte cose (scoping, @Singleton su A o B ma senza successo). Non voglio rompere il codice, e quelle iniezioni rendono i sensi.

Qualsiasi indizio sarà molto apprezzato.

risposta

10

Circular dependency injection is not required by the CDI standard, a meno che almeno un bean nel ciclo abbia un normal scope. La soluzione più semplice è dare A o B a un ambito normale. Se non è possibile fornire un ambito normale (dal modello di codice, sembra che abbiano tutti lo pseudo-scope predefinito @Dependent), sarà necessario cercare altre soluzioni. Pubblicare un esempio di codice reale potrebbe consentirci di aiutarti con una soluzione particolare, ma ecco un inizio:

  • È possibile combinare A e B nella stessa classe?
  • È possibile estrarre una nuova classe, C, da A e B, in modo che sia A che B, rispettivamente, @Inject C anziché l'altro?

Qui ci sono alcuni così legami con altre soluzioni che vi possono essere utili:

MVP with CDI; avoiding circular dependency

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

+0

Grazie di per la vostra risposta rapida. Devo ammettere che il concetto di portata normale non è molto chiaro per me. I collegamenti forniti forniscono commenti su @NormalScope, ma questo non esiste. Come dichiarare un ambito normale? – jmcollin92

+0

[La maggior parte degli ambiti sono ambiti normali.] (Http://docs.jboss.org/cdi/spec/1.0/html/contexts.html#normalscope) Gli ambiti di sessione, applicazione, conversazione e richiesta sono ambiti normali. Ciò è in contrasto con _pseudoscopes_: singleton e dependent (che è l'impostazione predefinita quando non si scrive in un'annotazione dell'oscilloscopio). – Nick

+0

Quindi, poiché ho già provato a dichiarare lo scope, questo dovrebbe funzionare, se capisco bene. Che tipo di ambito posso provare a un DAO (a cui si accede da un SessionBean)? – jmcollin92

4

ho risolto il problema utilizzando javax.inject.Provider esplicitamente. Anche se ritengo che questo dovrebbe essere fatto sotto la cappa di WELD automaticamente questo non era il mio caso. Questo ha funzionato per me e ha risolto il mio problema correlato.

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

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

non l'ho provato, ma potrebbe essere sufficiente per utilizzare un provider per rompere il ciclo, vale a dire non è necessario utilizzarlo in entrambe le classi.

1

deve iniettare un grado <B> invece di B (e/o Istanza <Un> invece di A)