2011-02-01 13 views
7

Supponiamo che ho due classi, prima di una classe senza proprietà, campi o annotazioni:CDI con gli oggetti non gestiti

public class B {} 

e una classe che ottiene B iniettato, in questo modo:

public class A { 
    @Inject 
    private B b; 

    public B getB() { 
     return b; 
    } 
} 

ora la classe A è abbastanza inutile fino a quando lo usiamo, quindi ci sono due opzioni:

  • @Inject esso
  • costruirlo manualmente, utilizzando il fidato "nuovo A()"

Se A viene iniettato, CDI gestisce ed è così gentile da iniettare B che ha lo scopo implicito di @Dependent. Fantastico, proprio quello che voglio.

Tuttavia, se costruisco manualmente A (diciamo in una fabbrica o un costruttore), CDI ignora completamente il mio scopo e non inietterà un oggetto di tipo B.

Esempio sto parlando quando si non funziona, qui oggetto a rimarrà sempre nullo:

public class Builder { 
    @Inject 
    private A a; 

    public static Builder ofTypeSomething() { 
     // do some magic here 
     return new Builder(); 
    } 

    private Builder() { 
     // and some more here 
    } 
} 

Perché questo non funziona?

Classe A è un bean gestito valido e ha un ambito valido, proprio come la classe B. Anche se aggiungo @Producer al metodo statico, non cambierà nulla (che va bene, causa l'idea della staticità il metodo è chiamarlo, non iniettare Builder da nessuna parte).

risposta

9

L'iniezione di dipendenza, sebbene utile, non è magica. Il modo in cui DI funziona è che quando si chiede al contenitore un'istanza di un oggetto, il contenitore prima lo costruisce (tramite new()) e quindi imposta le dipendenze (il modo in cui ciò accade dipende dal framework).

Se si costruisce l'entità, il contenitore non ha idea di aver costruito l'entità e non è possibile impostare le dipendenze dell'entità.

Se si desidera utilizzare una fabbrica, la maggior parte dei framework ha un modo di configurare l'entità in modo che il contenitore sappia effettuare una chiamata al metodo factory statica e non chiamare il costruttore dell'entità. Tuttavia, devi ancora ottenere la tua entità dal contenitore.

Modifica: This site sembra dimostrare come utilizzare una fabbrica in CDI.

+0

So che non è qualcosa di magico e capisco che il contenitore non sa nulla dell'oggetto. La domanda sarà quindi: in che modo CDI (sto usando Weld) mi consente di utilizzare una fabbrica? – Mythica

+0

Grazie, quella fabbrica è piuttosto utile! – Mythica

+1

Vero. Ma perché loro (i produttori di contenitori DI) rendono DI "magico"?!? È certamente fattibile (con un 'ClassFileTransformer', per esempio). –

Problemi correlati