Google guice 3.0 リリース間近、驚く内容です。
JSR-330 をサポートしDIとして確固たる地位を築いてくであろうことはさておき、
Constructor Bindings という驚くことができるようになる。(常々、これが欲しかった)
guice 2.0 までは、コンストラクタを指定してインスタンスをインジェクトさせるのに
@Provides や、Provider を使ってきた。
guice3.0 Constructor Bindings でコンストラクタを指定した binding では、
を指定されるコンストラクタのパラメータに任意インスタンスを注入して
コンストラクタ実行ができる。
さらに、このコンストラクタのクラスには、@Inject を記述する必要がないのに
パラメータに任意インスタンスが注入されることに注目したい。
つまり、Google guice を全く意識せずに作られた外部のクラスを Constructor Bindings で
インスタンス生成を制御していくのである。これが驚愕でした。
実験すると、
toConstructor で、コンストラクタを指定する。
以下は、Foo というインタフェースに、FooA クラスの String パラメータ1個の
コンストラクタを紐つかせている。
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
binder().bind(String.class).toInstance("abc");
try{
binder().bind(Foo.class).toConstructor(FooA.class.getConstructor(String.class));
}catch(NoSuchMethodException e){
throw new RuntimeException(e.getMessage(),e);
}
}
});
Foo を持って実行する Sample クラスが注入先、
Sample sample = injector.getInstance(Sample.class);
sample.exec();
// Foo と、FooA クラス
public interface Foo{
public String getValue();
}
// FooA クラスに、@Inject は、書かない!
public class FooA implements Foo{
private String s;
public FooA(){
this.s = "default construct!";
}
public FooA(String s){
this.s = s;
}
@Override
public String getValue(){
return this.s;
}
}
// Sample クラス
public class Sample{
@Inject Foo foo;
public void exec(){
System.out.println("Foo.getValue() = "+this.foo.getValue());
}
}
----------------
実行結果は、、、、
Foo.getValue() = abc