我的工厂如下,
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构造函数?
有什么想法吗?
答案 0 :(得分:50)
所有“Guice构造函数参数”的答案在某些方面似乎都是不完整的。 这是一个完整的解决方案,包括用法:
interface FooInterface{
String getFooName();
}
//在实现类
上注释构造函数和辅助参数class Foo implements FooInterface {
String bar;
@Inject
Foo(@Assisted String bar)
{
this.bar = bar;
}
// return the final name
getFooName(){
return this.bar;
}
}
//创建一个带有create()方法的工厂接口,该方法只接受辅助参数。
// FooFactory接口没有显式的实现类(Guice Magic)
interface FooFactory{
Foo create(String bar);
}
//将该工厂绑定到由AssistedInject创建的提供程序
binderModule implements Module{
void configure(Binder binder) {
binder.install(new FactoryModuleBuilder()
.implement(FooInterface.class, Foo.class)
.build(FooFactory.class));
}
}
//现在使用它:
class FooAction{
@Inject private FooFactory fooFactory;
doFoo(){
// Send bar details through the Factory, not the "injector"
Foo f = fooFactory.create("This foo is named bar. How lovely!");
f.getFooName(); // "This foo is named bar. How lovely!"
}
}
答案 1 :(得分:8)
您可能正在寻找的是使用Guice工厂。使用AssistedInject
功能特别容易,但它们有manual example at the top of the page。手动示例的缺点是,您可以使用非静态getFoo
方法获得工厂,您可以将任何参数传递给您需要的工具,并从那里构建对象。
如果你在Foo
中有方法拦截,这将不会直接起作用,但它会在许多其他情况下起作用。
要使用AssistedInject
,对我来说有一些更清晰的语义并且意味着更少的手动布线,你需要在类路径中使用guice-assistedinject扩展名,然后在创建Foo
时(嗯, FooImpl
,我们应该使用接口):
@Inject
public FooImpl(@Assisted String bar)
{
this.baz = bar;
}
然后创建一个FooFactory
界面:
public interface FooFactory {
public Foo create(String bar);
}
然后在你的guice模块中:
install(new FactoryModuleBuilder()
.implement(Foo.class, FooImpl.class)
.build(FooFactory.class));
您可以查看javadoc for FactoryModuleBuilder
以获取更复杂工厂的示例。
答案 2 :(得分:7)
我知道这是旧帖子,但我今天就自己解决了这个问题。 我只需要两个或最多三个不同的' Foo'而且我真的不想写出Factory的所有bolierplate代码。 通过一点谷歌搜索,我发现了Stubbisms – Tony’s Weblog我会建议这个解决方案,如果你确切知道你需要什么实例,这是完美的。
在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;
}
}
希望它有所帮助。
答案 3 :(得分:1)
如果这个类是工厂,它应该是一个Guice管理的对象,具有非静态getFoo方法,而getFoo方法只能使用
new Foo(bar)
并非每个类都需要由Guice实例化。
另请参阅AssistedInject,以避免自己创建此工厂并让Guice为您创建一个。