Nic*_*ner 11 java dependency-injection guice
我在启动时的代码中遇到以下错误:
尝试代理com.bar.Foo来支持循环依赖,但它不是一个接口.
这种代理究竟是如何工作的?如果我只是在接口后面抛出足够的类,一切都会好吗?
(我知道循环依赖通常是代码味道,但我认为在这种情况下它是可以的.)
Jan*_*ski 10
虽然"注入接口"方法是完全有效的,甚至在某些情况下甚至可能是更好的解决方案,但一般来说,您可以使用更简单的解决方案:提供商.
对于每个级别"A"guice可以管理,guice也提供" Provider<A>".这是javax.inject.Provider接口的内部实现,其get()消息将为" return injector.getInstance(A.class)".你不必自己实现界面,它是"guice magic"的一部分.
因此,您可以将A-> B,BA示例缩短为:
public class CircularDepTest {
static class A {
private final Provider<B> b;
private String name = "A";
@Inject
public A(Provider<B> b) {
this.b = b;
}
}
static class B {
private final Provider<A> a;
private String name = "B";
@Inject
public B(Provider<A> a) {
this.a = a;
}
}
@Inject
A a;
@Inject
B b;
@Before
public void setUp() {
Guice.createInjector().injectMembers(this);
}
@Test
public void testCircularInjection() throws Exception {
assertEquals("A", a.name);
assertEquals("B", a.b.get().name);
assertEquals("B", b.name);
assertEquals("A", b.a.get().name);
}}
Run Code Online (Sandbox Code Playgroud)
我更喜欢这个,因为它更具可读性(你不会因为构造函数已经拥有"B"的实例而感到愚蠢)并且由于你可以自己实现提供者,它仍然可以在guice上下文之外"手动"工作(用于测试例如).
我是这个概念的新手,但这是我的理解.
比方说,你有接口A和B,并实现Ai和Bi.
如果Ai依赖于B,并且Bi具有依赖性A,那么Guice可以创建A(调用它Ap)的代理实现,该代理实现将在将来的某个时刻被赋予Ai委托.吉斯给出了Ap到Bi其上的依赖A,从而Bi完成实例化.然后,因为Bi已被实例化,吉斯实例可以Ai用Bi.然后,由于Ai现在好了,Guice告诉Ap代表Ai.
如果A并且B不是接口(并且你只是Ai和Bi),这就不可能,因为创建Ap需要你扩展Ai,这已经需要了Bi.
以下是代码的外观:
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() {
}
}
Run Code Online (Sandbox Code Playgroud)
Guice制作的代理类如下所示:
public class Ap implements A {
private A delegate;
void setDelegate(A a) {
delegate = a;
}
public void doA() {
delegate.doA();
}
}
Run Code Online (Sandbox Code Playgroud)
它将全部使用这个基本想法连线:
Ap proxyA = new Ap();
B b = new B(proxyA);
A a = new A(b);
proxyA.setDelegate(a);
Run Code Online (Sandbox Code Playgroud)
如果你只有,Ai并且Bi没有接口A,那么这就是它的样子B.
public class Ap extends Ai {
private Ai delegate;
public Ap() {
super(_); //a B is required here, but we can't give one!
}
}
Run Code Online (Sandbox Code Playgroud)
如果我只是在接口后面抛出足够的类,一切都会好吗?
我猜想在构造函数中如何与代理进行交互有严格的限制.换句话说,如果B试图在Guice有机会用真实A填充A的代理之前调用A,那么我会期望一个RuntimeException.
| 归档时间: |
|
| 查看次数: |
7096 次 |
| 最近记录: |