私は次のような工場を持っています、
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)
{
}
}
OK。 Guiceを使用してこのパラメーターをFooコンストラクターに渡す方法がわかりませんか?
何か案は?
「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
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!"
}
}
これは古いスレッドであることは知っていますが、今日は自分で問題を見つけました。 「Foo」のインスタンスは2つまたは最大3つだけ必要であり、Factoryのすべての定型コードを記述したくはありませんでした。少しグーグルで見つけました 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;
}
}
それが誰かを助けることを願っています。
このクラスがファクトリーである場合、非静的getFooメソッドを持つGuice管理オブジェクトである必要があり、getFooメソッドは単に
new Foo(bar)
Guiceによってすべてのクラスをインスタンス化する必要はありません。
AssistedInject も参照してください。このファクトリーを自分で作成することを避け、Guiceに作成してもらいます。