【问题标题】:Using Assisted Inject with FactoryModuleBuilder in guice - Factory injection not being done在 guice 中使用带有 FactoryModuleBuilder 的辅助注入 - 工厂注入未完成
【发布时间】:2013-05-22 10:02:19
【问题描述】:

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

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

调用者类

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

}

【问题讨论】:

    标签: java guice guice-3 assisted-inject


    【解决方案1】:

    这里有两个问题。

    首先也是最重要的是,您不会在任何地方创建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 类的instance,该类将自动注入其字段。然后在执行实际工作的实例上调用方法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 注释。

    我已经写过关于静态的文章了。

    【讨论】:

    • 感谢弗拉基米尔的帮助,但这仍然不起作用。它在主类的 createInjector 中为 javax.inject.Provider 提供 noClassDefFoundError
    • @sachi1325,这是您的类路径的问题。 Guice 依赖于两个库, aopalliance 和 javax.inject。您的类路径中似乎缺少最后一个。我建议使用 maven,有了它你可能永远不会错过任何传递依赖。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    相关资源
    最近更新 更多