使用 Guice 将参数传递给构造函数

新手上路,请多包涵

我有一个工厂如下,

 public final class Application {

    private static IFoo foo;

    public static IFoo getFoo(String bar)
    {
        // i need to inject bar to the constructor of Foo
        // obvious i have to do something, not sure what
        Injector injector = Guice.createInjector();
        logger = injector.getInstance(Foo.class);
        return logger;
    }

}

这是 Foo 定义:

 class Foo
{
   Foo(String bar)
   {

   }

}

好的。我不确定如何使用 Guice 将此参数传递给 Foo 构造函数?

有任何想法吗?

原文由 DarthVader 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 522
2 个回答

所有“Guice Constructor Parameter”答案在某种程度上似乎都不完整。这是一个完整的解决方案,包括用法和视觉效果:

在此处输入图像描述

 interface FooInterface {
    String getFooName();
}

// 在实现类上注解构造函数和辅助参数

class Foo implements FooInterface {
    String bar;

    @Inject
    Foo(@Assisted String bar) {
        this.bar = bar;
    }

    // return the final name
    public String getFooName() {
        return this.bar;
    }

}

// 使用仅采用辅助参数的 create() 方法创建工厂接口。

// FooFactory 接口没有明确的实现类 (Guice Magic)

 interface FooFactory {
    Foo create(String bar);
}

// 将该工厂绑定到由 AssistedInject 创建的提供者

class BinderModule implements Module {

    public void configure(Binder binder) {
        binder.install(new FactoryModuleBuilder()
                .implement(FooInterface.class, Foo.class)
                .build(FooFactory.class));
    }
}

// 现在使用它:

 class FooAction {
    @Inject private FooFactory fooFactory;

    public String doFoo() {
        // Send bar details through the Factory, not the "injector"
        Foo f = fooFactory.create("This foo is named bar. How lovely!");
        return f.getFooName(); // "This foo is named bar. How lovely!"
    }
}

这里有很多帮助: https ://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/assistedinject/FactoryModuleBuilder.html

原文由 DougA 发布,翻译遵循 CC BY-SA 4.0 许可协议

我知道这是旧线程,但我今天自己才遇到这个问题。我只需要两个或最多三个不同的“Foo”实例,我真的不想编写 Factory 的所有 bolierplate 代码。通过一些谷歌搜索,我发现了这个 Stubbisms – Tony 的博客 我会建议这个解决方案,如果您确切知道您需要什么实例,它是完美的。

在 Guice 模块中:

     bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(new Provider<Foo>() {
        @Override
        public Foo get() {
            return new FooImpl("topic A");
        }
    });
    bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(new Provider<Foo>() {
        @Override
        public Foo get() {
            return new FooImpl("topic B");
        }
    });

或者在 Java 8 中:

     bind(Foo.class).annotatedWith(Names.named("firstFoo")).toProvider(() -> new FooImpl("first"));
    bind(Foo.class).annotatedWith(Names.named("secondFoo")).toProvider(() -> new FooImpl("second"));

在您需要 Foo 实例的服务构造函数中:

 @Inject
public MyService (
    @Named("firstFoo") Foo firstFoo,
    @Named("secondFoo") Foo secondFoo) {
}

在我的例子中是 Foo:

 public class FooImpl implements Foo {

    private String name;

    public FooImpl(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }
}

希望它能帮助别人。

原文由 NejcT 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题