在工厂注入未完成的情况下使用FactoryModuleBuilder辅助注入



我是一个向导新手,试图找出如何使用FactoryModuleBuilder在向导中实现辅助注入。我参考了实现FactoryModuleBuilder的java指南文档。

我已经完全按照文档里说的做了。不是注入工厂。我提到了这个堆栈溢出问题: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;
    }
}

你有两个问题。

首先,最重要的是,您没有在任何地方创建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 able,那么该类应该通过注入的方式只使用。您的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

我已经写过静态的

相关内容

  • 没有找到相关文章

最新更新