soy nuevo en este concepto, pero aquí está mi entendimiento.
Digamos que tiene interfaces A
y B
, y las implementaciones Ai
y Bi
.
Si Ai
tiene una dependencia en B
y Bi
tiene una dependencia en A
, a continuación, Guice puede crear una aplicación de proxy de A
(llámese Ap
) que en algún momento en el futuro ser objeto de una Ai
delegar a. Guice da ese Ap
a Bi
por su dependencia en A
, lo que permite Bi
finalizar la creación de instancias. Luego, como se ha creado una instancia de Bi
, Guice puede instanciar Ai
con Bi
. Entonces, desde Ai
ahora es bueno hacerlo, Guice dice Ap
para delegar en Ai
.
Si A
y B
no eran las interfaces (y sólo tenía Ai
y Bi
) esto no sería posible, porque la creación de Ap
que requieren volver a extender Ai
, que ya necesita un Bi
.
Esto es lo que podría ser similar con código:
clase
public interface A {
void doA();
}
public interface B {
void doB();
}
public class Ai implements A {
private final B b;
@Inject
public Ai(B b) {
this.b = b;
}
public void doA() {
b.doB();
}
}
public class Bi implements B {
private final A a;
@Inject
public Bi(A a) {
this.a = a;
}
public void doB() {
}
}
El proxy que Guice hace que se vería así:
public class Ap implements A {
private A delegate;
void setDelegate(A a) {
delegate = a;
}
public void doA() {
delegate.doA();
}
}
Y todo sería alámbrico con esta idea básica:
Ap proxyA = new Ap();
B b = new B(proxyA);
A a = new A(b);
proxyA.setDelegate(a);
y aquí es lo que sería como si sólo tuviera Ai
y Bi
, sin interfaces A
y B
.
public class Ap extends Ai {
private Ai delegate;
public Ap() {
super(_); //a B is required here, but we can't give one!
}
}
Si Acabo de tirar suficientes clases detrás de las interfaces, será todo bien?
Supongo que hay restricciones estrictas sobre cómo se puede interactuar con el proxy en el constructor. En otras palabras, si B intenta llamar a A antes de que Guice haya tenido la oportunidad de poblar el proxy de A con la A real, entonces esperaría una RuntimeException.
También prefiero este enfoque. Significa que no tiene que crear interfaces cuando de otro modo no las necesitaría. También es más rápido/menos potencialmente complicado cambiar la inyección a un proveedor que crear interfaces. – specialtrevor
¿Qué tal tener una dependencia explícita de 'Guice' en tu código de aplicación? Siempre he pensado que es bueno mantenerse independiente del marco DI. Antes de que introdujeses 'Provider' en tu código, podrías haber cambiado para decir' Spring' pero ya no es posible. –
Estoy hablando de javax.inject.Provider, una interfaz estándar JSR330. No se requiere dependencia de guice. –