大量の設定があり、それぞれに新しいバインディングアノテーションを作成したくない場合は、それらを列挙型に配置し、その列挙型を共通のバインディングアノテーションで使用してみてください。これは解決策が少し複雑かもしれませんが、避けようとしている定型文を節約することもできます。
このようにして、文字列(低速で脆弱)の代わりにオブジェクト参照(IDE対応)を照合し、それでも1つのバインディングアノテーションのみを作成できます。
public enum Config {
DB_NAME("db_name"),
DB_HOST("db_host_name_specified_in_file"),
SOME_NUMBER("some_number"),
;
private final String propertyName;
private Config(String propertyName) {
this.propertyName = propertyName;
}
public String getPropertyName() {
return propertyName;
}
public InjectConfig annotation() {
// Create an implementation of InjectConfig for ease of binding.
return new InjectConfig() {
@Override public Class<? extends Annotation> annotationType() {
return InjectConfig.class;
}
@Override public Config value() {
return Config.this;
}
@Override public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (!(obj instanceof InjectConfig)) {
return false;
}
return value() == ((InjectConfig) obj).value();
}
/** @see Annotation#hashCode */
@Override public int hashCode() {
return (127 * "value".hashCode()) ^ value().hashCode();
}
};
}
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public static @interface InjectConfig {
Config value();
}
}
これで、ループ内でそれぞれを繰り返してバインドできます。
public class YourModule extend AbstractModule {
@Override public void configure() {
// You can get a Provider in a Module as long as you
// don't call get() before the injector exists.
Provider<Settings> settingsProvider = binder().getProvider(Settings.class);
for (Config config : Config.values()) {
String propertyName = config.getPropertyName();
// Guice's TypeConverter will convert Strings to the right type.
bind(String.class).annotatedWith(config.annotation()).toProvider(
new GetValueFromSettingsProvider(settingsProvider, propertyName));
}
}
}
そして、必要なものだけを直接注入します。
/** Your constructor */
YourClass(@InjectConfig(DB_USER) String user,
@InjectConfig(SOME_NUMBER) int number) { }
これをテストする機会はありませんでしたが、私が知る限り、うまくいくはずです。特定の設定のユースケースを考えると、作成したものをマッサージするGetValueFromSettingsProvider
かgetConfigValueFromSettings
、列挙型にオーバーライド可能なメソッドを作成する必要がある場合があります。ただし、何らかの方法で(列挙型キー、ファイル内のプロパティ名、プロパティタイプ)タプルを格納する必要があることを忘れないでください。プログラムで管理するには、列挙型が最適な方法のようです。