gpt4 book ai didi

java - 在 Guice 中创建菱形对象图(无单例)

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:12:12 25 4
gpt4 key购买 nike

我正在使用 Guice 进行依赖注入(inject),并希望创建一个如下所示的对象图:

   d1        d2  /  \      /  \b1    c1  b2    c2  \  /      \  /   a1        a2
  • a1 and a2 denote instance of class A etc.
  • class A depends on classes B and C
  • classes B and C each depend on class D
  • However, the instance of D used in B and C should be the same

So I want to create two instances of the A class, each with this structure.A use case could be D being some kind of data object (say, a DB connection) that is used by the two clients B and C, that both are used in a servlet A.

Minimal Java class definition:

public class A {
@Inject A(B b, C c) {}
}

public class B {
@Inject B(D d) {}
}

public class C {
@Inject C(D d) {}
}

public class D {}

现在我可以创建 A 的两个实例:

Injector injector = Guice.createInjector(new DiamondModule());
A a1 = injector.getInstance(A.class);
A a2 = injector.getInstance(A.class);

但是,如果我这样做,我将得到四个不同的 D 实例,这不是我想要的。请注意,将 D 声明为单例将无济于事,因为那样我只会得到 D 的一个实例。

我看到了以下问题,但该问题的答案在这里不起作用,或者至少我不知道如何:Guice inject single instance into multiple objects without using @Singleton

有没有人知道如何解决这个问题?或者这个设计有什么问题吗?或者这已经是我必须声明自己的范围的实例了吗?


解决方案

与此同时,我注意到这个问题与 Dependency injection: Scoping by region (Guice, Spring, Whatever) 重复,并根据该问题的答案,我想出了一个解决方案。

基本思想是为钻石的每个实例创建一个新的注入(inject)器,如下所示:

public class MainModule extends AbstractModule {
@Override
protected void configure() {
}

@Provides
A createA() {
return Guice.createInjector().getInstance(A.class);
}
}

现在让 D 成为一个单例,它的作用域是特定的注入(inject)器。

// class D is a singleton
@Singleton
public class D {}

最佳答案

这被称为“机器人腿”问题(创建具有略微不同实例的相似图)并得到处理 here .

class LegModule extends PrivateModule {
private final Class<? extends Annotation> annotation;

LegModule(Class<? extends Annotation> annotation) {
this.annotation = annotation;
}

@Override protected void configure() {
bind(Leg.class).annotatedWith(annotation).to(Leg.class);
expose(Leg.class).annotatedWith(annotation);

bindFoot();
}

abstract void bindFoot();
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(
new LegModule(Left.class) {
@Override void bindFoot() {
bind(Foot.class).toInstance(new Foot("leftie"));
}
},
new LegModule(Right.class) {
@Override void bindFoot() {
bind(Foot.class).toInstance(new Foot("righty"));
}
});
}

关于java - 在 Guice 中创建菱形对象图(无单例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42664171/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com