如果我理解正确,你有类似的东西
public class C {
}
public class A {
private C c;
public void setC(C c) {
this.c = c;
}
}
public class B {
private final C c;
public B() {
this.c = new C();
}
public C getC() {
return this.c;
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
A a = new A();
C c = b.getC();
a.setC(c);
}
}
这种设计不遵循 DI 原则,应该重构。您应该让 Guice 创建您的C
实例。在这种情况下,您将拥有类似的东西
public class C {
}
public class A {
private final C c;
@Inject
A(C c) {
this.c = c;
}
}
public class B {
private final C c;
@Inject
B(C c) {
this.c = c;
}
}
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector();
A a = injector.getInstance(A.class);
B b = injector.getInstance(B.class);
}
}
在这里,您已经C
自动注入A
和B
。
如果您真的无法重构代码,请考虑使用提供程序:
public class AProvider extends Provider<A> {
private final B b;
@Inject
AProvider(B b) {
this.b = b;
}
@Override
public A get() {
A a = new A();
C c = b.getC();
a.setC(c);
// Or, better
// A a = new A(b.getC());
return a;
}
}
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(A.class).toProvider(AProvider.class);
}
});
A a = injector.getInstance(A.class);
}
}
在这种情况下,提供者用于创建A
和设置其C
依赖项。
但有时即使这样还不够(例如,当您的B.getC()
行为取决于用户输入时)。在这种情况下,您必须使用辅助注入扩展:
public interface AFactory {
public A create(C c);
}
public class A {
private final C c;
private final Other other;
@Inject
A(@Assisted C c, Other other) {
this.c = c;
this.other = other;
}
}
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
@Inject
protected void configure() {
install(new FactoryModuleBuilder()
.build(AFactory.class));
}
});
B b = injector.getInstance(B.class);
C c = b.getC(someUserInput);
AFactory af = injector.getInstance(AFactory.class);
A a = af.create(c);
}
}
A
在最后一个示例中,将通过调用注入两个对象af.create(c)
:首先,c
您提供的对象,其次Other
是由 Guice 自动解析的类的实例。换句话说,辅助注入允许您实例化类,这些类的一部分依赖关系由您解决,另一部分由 Guice 解决。