Google guice の Named アノテーションは、やはり便利であると思う。
あるクラスのインスタンスを Properties や、Map が示す状況で
初期インスタンスを作成したい時に、@Named( Key ) をつけた Field に初期値を
Properties や、Map の Key が示す値にして生成することを簡単にできる。
ターゲットとして、Sample クラスがあり、@Inject と @Named を
初期化したいフィールドに付与する。
import com.google.inject.Inject;
import com.google.inject.name.Named;
public class Sample{
@Inject @Named("USER") private String user;
@Inject @Named("DOMAIN") private String domain;
@Inject @Named("SIZE") private long size;
@Inject @Named("BIT") private byte bit;
:
// getter , setter 等を用意
}
ファクトリメソッドとして@Namedが示すKeyのValueをインジェクトは、以下のように
用意できる
import java.util.Map;
import java.util.Properties;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;
public final class ObjectFactory{
private ObjectFactory(){}
public static <T> T createInstance(Class<T> cls,Properties prop){
final Properties p = prop;
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
Names.bindProperties(binder(),p);
}
}
);
return injector.getInstance(cls);
}
public static <T> T createInstance(Class<T> cls,Map<String,String> map){
final Map<String,String> m = map;
Injector injector = Guice.createInjector(new AbstractModule(){
@Override
protected void configure(){
Names.bindProperties(binder(),m);
}
}
);
return injector.getInstance(cls);
}
}
実行は、
Properties p = new Properties();
p.setProperty("USER","Nadia");
p.setProperty("DOMAIN","Jupiter");
p.setProperty("SIZE","24");
p.setProperty("BIT","127");
Sample s = ObjectFactory.createInstance(Sample.class,p);
Map<String,String> m = new HashMap<String,String>();
m.put("USER","Rachel");
m.put("DOMAIN","Mars");
m.put("SIZE","32");
m.put("BIT","64");
Sample s = ObjectFactory.createInstance(Sample.class,m);
ただし、対象フィールドが、プリミティブ型でないとダメである。
こういうメソッドを抱えるクラスの命名が難しい。