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

Java 使用Guice将参数传递给构造函数,java,dependency-injection,guice,Java,Dependency Injection,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 Inj

我有一个工厂,如下所示

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构造函数


有什么想法吗?

如果这个类是一个工厂,它应该是一个Guice管理的对象,有一个非静态的getFoo方法,getFoo方法只需使用

new Foo(bar)
并非每个类都需要由Guice实例化


另请参见,为了避免自己创建此工厂,请让Guice为您创建一个工厂。

您可能正在寻找的是使用Guice工厂。功能特别简单,但它们有一个。手动示例的不足之处在于,您可以在非静态
getFoo
方法下获取工厂,您可以将任何参数传递给所需的对象,并从中构建对象

如果您在
Foo
中有方法拦截,这将不会直接起作用,但在许多其他情况下它会起作用

要使用
AssistedInject
,它对我来说语义更清晰,意味着更少的手动连接,您需要类路径中的扩展,然后在创建
Foo
时(嗯,
FooImpl
,我们应该使用接口):

然后创建一个
FooFactory
界面:

public interface FooFactory {
    public Foo create(String bar);
}
然后在GUI模块中:

install(new FactoryModuleBuilder()
    .implement(Foo.class, FooImpl.class)
    .build(FooFactory.class));
    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");
        }
    });
您可以查看更复杂工厂的示例

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

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

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)

//将该工厂绑定到由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!"
    }
}

这里有很多帮助:

我知道这是一条老线索,但今天我自己也遇到了这个问题。 我只需要两个或最多三个不同的'Foo'实例,我真的不想写工厂的所有bolierplate代码。 通过一点谷歌搜索,我发现了这一点,我建议这个解决方案是完美的,如果你确切地知道你需要什么样的实例

在GUI模块中:

install(new FactoryModuleBuilder()
    .implement(Foo.class, FooImpl.class)
    .build(FooFactory.class));
    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");
        }
    });
在需要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;
    }
}

希望它能帮助别人。

是的,它很糟糕,它太复杂了,structuremap比guice灵活得多。我在哪里可以下载structuremap for Java?对我来说不适用。我有NullPointerException,因为Foo构造函数从未调用过。可能您需要在某个地方使用您的模块?请修复“create”方法(FooFactory接口)缺少的返回类型。它必须是:Foo create(字符串栏);
@Inject
public MyService (
    @Named("firstFoo") Foo firstFoo,
    @Named("secondFoo") Foo secondFoo) {
}
public class FooImpl implements Foo {

    private String name;

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

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