2

我是一个 guice 新手,试图弄清楚如何使用 FactoryModuleBuilder 在 guice 中实现辅助注入。我查阅了 guice java 文档以实现FactoryModuleBuilder

我已经按照文档中的说明完成了所有操作。它没有注入工厂。我提到了这个堆栈溢出问题:Guice AssistedInject 不会注入 有同样问题的工厂。它讨论了构造函数注入问题之前的字段注入。我跟着它,我试图使用调用者类调用父类,但我仍然得到空指针异常。这里出了什么问题?

调用者类

public class MAIN {

    @Inject private static MyFactory factory;

    public static void main(String[] args){
        ParentClass newbie = new ParentClass(factory);
    }
}

我仍然遇到异常:

Exception in thread "main" java.lang.NullPointerException
    at com.pkg.ParentClass.<init>(ParentClass.java:19)
    at com.pkg.MAIN.main(MAIN.java:10)

家长班

public class ParentClass {

    private final Foo test;
    @Inject
    public ParentClass(MyFactory factory){
        test = factory.create(new HashMap<String,Object>());
    }
}

模块实现:ParentModule

public class ParentModule extends AbstractModule{

    @Override
    protected void configure() {
        install(new FactoryModuleBuilder()
                .implement(Foo.class, FooImpl.class)
                .build(MyFactory.class));
    }

}

工厂接口:MyFactory

public interface MyFactory {

    Foo create(Map<String,Object> map);
}

类接口:Foo

public interface Foo{
}

类:FooImpl

public class FooImpl implements Foo {

    private final Map<String,Object> mapA;
    @AssistedInject
    public FooImpl(@Assisted Map<String,Object> map){

        mapA=map;
    }

}
4

1 回答 1

3

你这里有两个问题。

首先也是最重要的,你不是Injector在任何地方创造。显然,没有注射器,任何事情都不会奏效。您必须使用您的模块创建一个注入器实例:

Injector injector = Guice.createInjector(new ParentModule());

您的第二个问题是您想将工厂注入静态字段:

@Inject private static MyFactory factory;

尽管如果您明确告诉 Guice 可以使用静态字段,但它被认为是非常糟糕的做法。除非您使用一些遗留代码,否则您永远不应该注入静态字段。

你真正想要的是这样的:

public class Main {
    @Inject
    private MyFactory factory;

    public void run() {
        ParentClass newbie = new ParentClass(factory);
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new ParentModule());
        Main main = injector.getInstance(Main.class);
        main.run();
    }
}

请注意,程序入口点 ( main) 现在创建了一个注入器,然后使用它创建一个类的实例Main该实例将自动注入其字段。run()然后它在执行实际工作的实例上调用方法。

但是请注意,这一切用于辅助注射的说明性目的才真正有效。你不应该像这样构造你的真实代码。例如,您正在使用new运算符创建其构造函数用@Inject. 永远不要这样做!如果你将某个类(即它的构造函数或字段)标记为@Injectable,那么这个类只能通过注入的方式使用。您的Main代码可以缩短为以下内容:

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new ParentModule());
        ParentClass newbie = injector.getInstance(ParentClass.class);
    }
}

这里newbie将自动接收一个实例MyFactory到它的构造函数中,因为它被注释了@Inject

我已经写过关于静力学的文章。

于 2013-05-22T11:21:02.030 回答