在guice中使用带有FactoryModuleBuilder的Assisted Inject - 未完成工厂注入

时间:2013-05-22 10:02:19

标签: java guice guice-3 assisted-inject

我是一名新手试图弄清楚如何使用FactoryModuleBuilder在guice中实现辅助注入。我咨询了guice java docs以实现FactoryModuleBuilder

我完全按照文档中的说法完成了所有工作。 它没有注入工厂。 我提到了这个堆栈溢出问题:Guice AssistedInject won't inject the factory 这有同样的问题。 它讨论了构造函数注入问题之前的场注入。我跟着它,我试图使用调用者类调用Parent类,但我仍然得到空指针异常。这里出了什么问题?

来电者专场

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;
    }

}

1 个答案:

答案 0 :(得分: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注释的类。不要这样做!如果您将某个类(即其构造函数或字段)标记为@Inject,则应通过注入方式将此类仅用于 。您的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注释。

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