Properties 読込みを考え直す。

Java の Properties 、properties ファイル読込みは古くから存在して過去、
設定ファイル地獄で皆、苦しんだ歴史がある。そして、convention over configuration が提唱され
それでも日本の多くのシステム屋は、うまくバランスを持ってきたとは言い難い。。
properties ファイルの使用と保守は、完全に消滅することはないだろう。

properties ファイルを読むのに、直接 ResourceBundle で読む方法と、あくまでもファイルIOとして
Properties の load メソッドを使う方法、あるだろう。
それから、複数の properties ファイルがある場合に、どう読み込んで管理するとなると、
これもシステムによって様々な方法になってしまう。

直接 ResourceBundle で、読む方法
例えば、システムクラスローダのPATHが通ったとろで、
message.properties というファイルのプロパティを読む、(2バイト文字も読めるようにする)

ResourceBundle rs = ResourceBundle.getBundle("message", new ResourceBundle.Control(){
   @Override
   public ResourceBundle newBundle(String baseName, Locale locale, String format
, ClassLoader loader, boolean reload)
   throws IllegalAccessException, InstantiationException, IOException{
      try(InputStreamReader sr = new InputStreamReader(
      loader.getResourceAsStream(
toResourceName(toBundleName(baseName, locale), "properties")), "UTF-8");
BufferedReader reader = new BufferedReader(sr)
      ){
         return new PropertyResourceBundle(reader);
      }
   }
});

Properties p = new Properties();
for(String key : rs.keySet()){
   p.setProperty(key,rs.getString(key));
}

こんな感じになる。。。
そこで、今まで Properties の読込みはいくつも過去に書いてきたし整理したくもなり、
まとめた。。。
Properties · yipuran/yipuran-core Wiki · GitHub
このライブラリを使用して、、、
実践的には、Properties 読込み使用の処理を書いていくので、、、
サンプルとしては、、、

import java.util.Properties;
import javax.inject.Inject;
import org.yipuran.env.PropertyInject;

public class Logic{
   @Inject @PropertyInject private Properties prop;
   
   public Properties getProperties(){
      return prop;
   }
}

という、PropertyInject アノテーションで指定する Properties へのインジェクションを

import org.yipuran.env.PropertyBindModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
Injector injector = Guice.createInjector(new PropertyBindModule("message"));
Logic logic = injector.getInstance(Logic.class);

Properties p = logic.getProperties();

この PropertyBindModule で、message.properties に結びつくように、簡潔にするように
yipuran-core ライブラリが提供する処理で実装している

さらに、複数の properties ファイルが存在するケースへの対応を考えて、、

public interface MLogic{
   public String getValue(String key);
}
import java.util.Optional;
import java.util.Properties;
import javax.inject.Inject;
import org.yipuran.env.PropertyInject;

public class LogicImpl implements MLogic{
   @Inject @PropertyInject("aaa") private Properties propA
   @Inject @PropertyInject("bbb") private Properties propB;

   @Override
   public String getValue(String key){
      return Optional.ofNullable(propA.getProperty(key)).orElse( propB.getProperty(key, "not value" ) );
   }
}

これで、aaa.properties と bbb.properties 両方を読み込み、aaa.properties に存在しなかったら、
bbb.properties の方の値を探して返す。
という対応をする。

import org.yipuran.env.PropertyBindModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
Injector injector = Guice.createInjector(new PropertyBindModule());
MLogic logic = injector.getInstance(LogicImpl.class);

logic.getValue(key) で Properties の 値を取得