java - Guice 代理支持循环依赖

标签 java dependency-injection guice

启动时我的代码出现以下错误:

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

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

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

最佳答案

虽然“注入(inject)接口(interface)”方法是完全有效的,并且在某些情况下甚至可能是更好的解决方案,但一般来说,您可以使用更简单的解决方案:Providers。

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

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

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”的实例)并且因为你可以自己实现提供者,它仍然可以“手动”工作,在guice 上下文(例如用于测试)。

关于java - Guice 代理支持循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10014825/

相关文章:

Java JDI 转换为实际的真实类型

java - 观察者在更改后停止

java - 使用来自文本文件的输入在 java 中构建树

dependency-injection - CaSTLe - 使用构造函数注入(inject)类型工厂注入(inject)组件时,属性注入(inject)无法解析依赖关系

javascript - 在运行时配置 RequireJS

java - Digital Ocean为spring boot应用开放8080端口

java - 哪种Java Web Framework最适合Google Guice?

java - Struts2 中的 Guice 3

java - 验证是否从构造函数调用了方法

java - CDI 的实例或 Guice 提供者的 Spring 等效项是什么