2011-02-01 15 views
7

Supongamos que tengo dos clases, por primera vez una clase sin ningún tipo de propiedades, campos o anotaciones:CDI con objetos no administrados

public class B {} 

y una clase que obtiene B inyectada, así:

public class A { 
    @Inject 
    private B b; 

    public B getB() { 
     return b; 
    } 
} 

ahora la clase A es bastante inútil hasta que la usamos, por lo que hay dos opciones:

  • @Inject que
  • construirlo manualmente, utilizando la confianza "nueva A()"

Si se inyecta A, CDI lo administra y es tan amable de inyectar B, que tiene el alcance implícito de @Dependent. Genial, justo lo que quiero.

Sin embargo, si construyo manualmente A (digamos en una fábrica o un constructor), CDI ignora por completo mi objeto y no inyectará un objeto de tipo B.

Ejemplo estoy hablando cuando se no funciona, aquí el objeto a siempre permanecerá nulo:

public class Builder { 
    @Inject 
    private A a; 

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

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

¿Por qué no funciona?

La clase A es un bean gestionado válido y tiene un alcance válido, al igual que la clase B. Incluso si agrego @Producer al método estático, no cambiará nada (lo cual está bien, la idea de la estática método es llamarlo, no inyectar el Constructor en ninguna parte).

Respuesta

9

La inyección de dependencia, si bien es útil, no es mágica. La forma en que DI funciona es que cuando le pides al contenedor una instancia de un objeto, el contenedor primero lo construye (a través del new()) y luego establece las dependencias (cómo esto sucede depende de tu marco).

Si construye la entidad usted mismo, entonces el contenedor no tiene idea de que ha construido la entidad y no puede establecer las dependencias de la entidad.

Si desea utilizar una fábrica, la mayoría de los marcos tienen alguna forma de configurar la entidad para que el contenedor sepa realizar una llamada a método de fábrica estático y no llamar al constructor de la entidad. Sin embargo, aún debe obtener su entidad del contenedor.

Editar: This site parece demostrar cómo utilizar una fábrica en CDI.

+0

Sé que no es algo mágico y entiendo que el contenedor no sepa nada sobre el objeto. La pregunta entonces será: ¿cómo me permite CDI (estoy usando Weld) usar una fábrica? – Mythica

+0

¡Gracias, esa fábrica es bastante útil! – Mythica

+1

Es cierto. ¿Pero por qué ellos (los vendedores de contenedores DI) no hacen DI "mágico"?!? Sin duda es factible (con un 'ClassFileTransformer', por ejemplo). –

Cuestiones relacionadas