Google guice 3.0 がリリースされて新機能の1つに、AssistedInject の Factory生成がある。
guice 2.0 では、
bind(PaymentFactory.class).toProvider(FactoryProvider.newFactory(
PaymentFactory.class, RealPayment.class));
toProvider でFactoryProvider.newFactory の結果を指定したりしていた。
guice 3.0 では、
configure()の中で記述する install に渡す Module を
com.google.inject.assistedinject.FactoryModuleBuilder の buildメソッドで
生成する。
以下のサンプルのように、Factory のインターフェースだけでその実装クラスを記述しないで
済むことと、
下記サンプルのように、Factory インターフェースのメソッドにアノテーションで
別々のクラスのインスタンスを生成できることが多くの可能性を期待できる。
(下記→ AnnotatedCarFactory)
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.name.Names;
:
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
binder().bind(String.class).toInstance("Test body!");
install(new FactoryModuleBuilder().build(AllCarFactory.class));
}
});
AllCarFactory allfactory = injector.getInstance(AllCarFactory.class);
Mustang mustang = allfactory.getMustang("RED");
Beetle beetle = allfactory.getBeetle("GREEN");
System.out.println(mustang.getClass().getName()+"\t"+mustang.color()+"\t body = "+mustang.body());
System.out.println(beetle.getClass().getName()+"\t"+beetle.color()+"\t body = "+beetle.body());
Injector injector2 = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
binder().bind(String.class).toInstance("Test body!");
install(new FactoryModuleBuilder()
.implement(Car.class,Names.named("America"),Mustang.class)
.implement(Car.class,Names.named("German"),Beetle.class)
.build(AnnotatedCarFactory.class));
}
});
AnnotatedCarFactory anofactory = injector2.getInstance(AnnotatedCarFactory.class);
Car mustang2 = anofactory.getAmericanCar("RED");
Car beetle2 = anofactory.getGermanCar("GREEN");
System.out.println(mustang2.getClass().getName()+"\t"+mustang2.color()+"\t body = "+mustang2.body());
System.out.println(beetle2.getClass().getName()+"\t"+beetle2.color()+"\t body = "+beetle2.body());
------------------------------------
public interface AllCarFactory{
public Mustang getMustang(String color);
public Beetle getBeetle(String color);
}
------------------------------------
import javax.inject.Named;
public interface AnnotatedCarFactory{
@Named("America") public Car getAmericanCar(String color);
@Named("German") public Car getGermanCar(String color);
}
------------------------------------
public interface Car{
public String color();
public String body();
}
------------------------------------
package test.factorymodulebuild;
import javax.inject.Inject;
import com.google.inject.assistedinject.Assisted;
public class Mustang implements Car{
private String color;
private String body;
@Inject
public Mustang(@Assisted String color,String body){
this.color = color;
this.body = body;
}
@Override
public String color(){
return this.color;
}
@Override
public String body(){
return this.body;
}
}
------------------------------------
package test.factorymodulebuild;
import javax.inject.Inject;
import com.google.inject.assistedinject.Assisted;
public class Beetle implements Car{
private String color;
private String body;
@Inject
public Beetle(@Assisted String color,String body){
this.color = color;
this.body = body;
}
@Override
public String color(){
return this.color;
}
@Override
public String body(){
return this.body;
}
}
------------------------------------
実行結果は、、、
test.factorymodulebuild.Mustang RED body = Test body!
test.factorymodulebuild.Beetle GREEN body = Test body!
test.factorymodulebuild.Mustang RED body = Test body!
test.factorymodulebuild.Beetle GREEN body = Test body!
------------------------------------
JSR-330 サポートにより、com.google.inject.name.Named ではなく、
javax.inject.Named の使用でOKなのもここで証明されuた