当前位置: 首页 > 知识库问答 >
问题:

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

端木澄邈
2023-03-14

我是一名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;
    }

}

共有1个答案

曾新立
2023-03-14

这里有两个问题。

首先也是最重要的一点,您没有在任何地方创建喷油器。显然,没有喷油器,什么都不会工作。您必须使用模块创建喷油器实例:

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)现在创建一个注入器,然后使用它创建一个类的实例,该类将自动注入其字段。然后对执行实际工作的实例调用方法run()

然而,请注意,这一切仅对辅助注射的说明目的有效。您不应该这样构造真正的代码。例如,您正在使用new操作符创建类,这些类的构造函数用@Inject注释。永远不要这样做!如果将某个类(即其构造函数或字段)标记为可注入,则该类只能通过注入的方式使用。您的主代码可以缩短为以下内容:

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

这里新手将自动将MyFactory的实例接收到其构造函数中,因为它用@Inject注释。

我已经写过静力学了。

 类似资料:
  • 我一直在用guice做一个项目。 我有一个抽象类,它有很多实现。为了使用正确的实现,我使用一个工厂,它接收参数,然后返回正确的实例。 演示代码 我想知道的是,如果我可以用替换工厂,直接注入的实现(请注意,它们应该使用辅助注入)? 谢谢你。

  • 这是一个奇怪的用例,我需要一些帮助来弄清楚如何相互结合使用辅助/提供者/FactoryModuleBuilders。忽略的缺失。这只是一个例子。 属于我无法更改的库的一组特征具有以下模式。它使用蛋糕图案。 由于这些特征不能被直接注入,我创建了一个允许它们被注入的包装器 在我的代码中,我有一个依赖于服务的控制器,而服务又依赖于库。根据控制器的需要,服务应能够使用“BB”或“CC”。组件如下所示 我将

  • 我正在使用Guice Assisted Inject库为我建立一个工厂。我目前的设置如下: 这迫使我使用< code > factory . create controller(first,factory . create second(first))显式创建一个< code>SecondDep。是否可以更改我的绑定,这样我就可以简单地执行< code > factory . create con

  • 我有这个接口和简单的实现: 我想使用Guice用不同的方法生成一个。

  • 目前,我将辅助注射与命名参数一起使用,如下所示: 这很棒。但是我认为使用字符串作为参数的标识符有点难看。我想做的是以下内容: 所以本质上我想要自定义辅助注释。有办法做到这一点吗?

  • 假设有一个类A,它的构造函数是这样的: 还有AFactory: 所以要创建一个A的实例,我显然需要做这样的事情: 但是,假设我有其他类:例如,B类、C类和D类具有类型为A的成员(带有字段注入,但也可以是ctor): 我希望将 A 的相同实例注入到这些类中。但仍然可以选择将 A 的另一个实例注入其他类(假设 E 类和 F 类)。 正确的做法是什么?我就是想不出一个干净的方法来做到这一点。