Guice代理支持循环依赖 [英] Guice proxying to support circular dependency

查看:762
本文介绍了Guice代理支持循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在启动时的代码中遇到以下错误:

I'm getting the following error in my code at launch:


尝试代理com.bar.Foo以支持循环依赖,但它是
而不是界面。

Tried proxying com.bar.Foo to support a circular dependency, but it is not an interface.

这种代理究竟是如何工作的?如果我只是在接口后面抛出足够的类,一切都会好吗?

How exactly does this proxying work? If I just throw enough classes behind interfaces, will everything be fine?

(我知道循环依赖通常是代码味道,但我认为在这种情况下它没关系。 )

(I know that circular dependencies are usually a code smell, but I think in this case it's ok.)

推荐答案

虽然注入接口方法完全有效,甚至在某些情况下可能是更好的解决方案,一般情况下,你可以使用一个更简单的解决方案:提供商。

While the "inject an interface" approach is totally valid, and might even be the better solution in some occasions, in general, you can use a simpler solution: Providers.

对于每个A类可以管理的类,guice还提供提供商< A> ; 。这是javax.inject.Provider接口的内部实现,其 get()消息将返回injector.getInstance(A.class) 。您不必自己实现接口,它是guice magic的一部分。

For every class "A" guice can manage, guice also offers a "Provider<A>". This is an internal implementation of the javax.inject.Provider-interface, whose get() message will "return injector.getInstance(A.class)". You dont have to implement the Interface yourself, its part of the "guice magic".

因此,您可以将A-> B,BA示例缩短为:

Thus you can shorten the A->B, B-A example to:

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);
}}

我更喜欢这个,因为它更具可读性(你不会被愚弄相信构造函数已经拥有一个B实例,并且由于你可以自己实现Providers,它仍然可以在guice上下文之外手动工作(例如用于测试)。

I prefer this, because its more readable (you are not fooled to beleive that the constructor already holds an instance of "B") and since you could implement the Providers yourself, it would still work "by Hand", outside the guice context (for testing for example).

这篇关于Guice代理支持循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆