有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在guice中使用FactoryModuleBuilder的辅助注入未完成工厂注入

我是一名guice新手,试图弄清楚如何使用FactoryModuleBuilder在guice中实现辅助注入。我参考了guicejava文档来实现FactoryModuleBuilder

我做的每件事都和文件上说的一模一样。 这不是工厂的问题。 我提到了这个堆栈溢出问题:Guice AssistedInject won't inject the factory 也有同样的问题。 它讨论了构造函数注入之前的字段注入问题。我遵循它,并尝试使用调用方类调用父类,但仍然得到null指针异常。这里出了什么问题

调用方类

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

模块实现:父模块

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) 个答案

  1. # 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类的实例,该类将自动注入其字段。然后对执行实际工作的实例调用方法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注释

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