如何将对象传递给稍后将注入的类

时间:2013-09-05 14:43:35

标签: java oop guice guice-3

我是google guice的新手。

我正在编写一个nexus插件,其中nexus会注入一些类。例如,说要在 A类中注入的类。

在注入A类之前,我有另一个实例化的 B类,在其中我有一个方法,其中一个对象(比如obj)被初始化。

我必须将这个初始化对象传递给A类。

通常,如果实例化在我们的控制之下,我将按

进行
A a = new A();

A.setObject(obj);

但是现在假设该类将被系统注入,我不知道如何将这个初始化对象传递给这个类A.

1 个答案:

答案 0 :(得分:1)

如果我理解正确,你会有类似

的内容
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会自动注入AB

如果确实无法重构您的代码,请考虑使用提供商:

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()行为取决于用户输入时)。在这种情况下,您必须使用assisted inject扩展名:

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。