ResourceBundle.Controlクラスをオーバーライドすることによって、リソースバンドルをより細かく制御できるようになります。
まず最初に、リソースバンドルのプロパティファイルを、プログラムの実行中に変更し、変更したプロパティ値を実行中のプログラムに反映させるプログラミングを行ってみます。
package jp.gr.java_conf.torutk.coding.resourcebundle; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Locale; import java.util.ResourceBundle; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; /** * ResourceBundleのキャッシュ時間を制御し、プロパティファイルの更新を * プログラム実行中に反映する実験プログラム(クラス)。 * * @link ResourceBundle * @link ResourceBundle.Control */ public class ResourceBundleApp extends JFrame { private static Logger logger = Logger.getLogger( "jp.gr.java_conf.torutk.coding.resourcebundle" ); private JButton updateButton; private JLabel messageLabel; private long timeToLive = 30 * 1000; private ResourceBundle.Control resourceBundleControl; /** * コンストラクタ。 * リソースバンドル制御用のResourceBundle.Control匿名クラスを * 生成し、またGUIを構成するパーツを生成する。 */ public ResourceBundleApp() { super("ResourceBundle cache experiment"); resourceBundleControl = new ResourceBundle.Control() { public long getTimeToLive(String aBaseName, Locale aLocale) { return timeToLive; } }; updateButton = createUpdateButton(); add(updateButton, BorderLayout.SOUTH); messageLabel = createMessageLabel(); add(messageLabel, BorderLayout.CENTER); } /** * 更新ボタンを生成する。 * 更新ボタンのアクション */ private JButton createUpdateButton() { JButton button = new JButton("Update"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent anEvent) { String text = getMessageFromResource(); messageLabel.setText(text); } } ); return button; } /** * メッセージ表示ラベルを生成する。 */ private JLabel createMessageLabel() { String text = getMessageFromResource(); JLabel label = new JLabel(text); return label; } /** * リソースバンドルのキャッシュ時間を設定する。 */ public void setTimeToLive(final long aTimeToLive) { logger.info("setting new value = " + aTimeToLive); timeToLive = aTimeToLive; } /** * リソースバンドルからメッセージ文字列を取得する。 * * リソースバンドル(プロパティ・ファイル)の更新を反映するには * 毎回getBundle(..)を呼び出す必要がある。 * * @throws MissingResourceBundle */ private String getMessageFromResource() { long startTime = System.nanoTime(); ResourceBundle resource = ResourceBundle.getBundle( "jp.gr.java_conf.torutk.coding.resourcebundle.MyResource", resourceBundleControl ); long stopTime = System.nanoTime(); String text = resource.getString("message"); logger.info( "message = {" + text + "}, it takes " + (stopTime - startTime)/1000 + " us." ); return text; } /** * リソースバンドル・キャッシュ実験プログラムを起動する。 * * コマンドライン・オプション * <li>[-ttl <time to live>] キャッシュ時間(ms)<br> * ちなみに、-1を指定するとTTL_DONT_CACHE, -2を指定するとTTL_NO_EXPIRATION_CONTROLになります。 * */ public static void main(final String[] args) { ResourceBundleApp app = new ResourceBundleApp(); for (int i=0; i<args.length; ++i) { if ("-ttl".equals(args[i])) { app.setTimeToLive(Long.valueOf(args[++i])); } } app.setBounds(320, 100, 480, 256); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); app.setVisible(true); } }
Java 2 SE 5.0までのjava.util.ResourceBundleクラスは、一度プロパティファイルから取得した値はずっとメモリ中に保持し続けています。そのため、プログラムを実行中にプロパティファイルを変更しても、getBundleメソッドで取得したリソースバンドルは古い内容のままです。変更内容をプログラムに反映するにはプログラムの再起動が必要です。
ResourceBundle resource = ResourceBundle.getBundle( "jp.gr.java_conf.torutk.coding.resourcebundle.MyResource" ); String text = resource.getString("message");
Java SE 6(Mustang)ではjava.util.ResourceBundleクラスが改善され、プロパティファイルの内容をメモリ中に保持している期間を制御することができるようになりました。
ResourceBundle resource = ResourceBundle.getBundle( "jp.gr.java_conf.torutk.coding.resourcebundle.MyResource", new ResourceBundle.Control() { public long getTimeToLive(String baseName, Locale locale) { return 60 * 1000; // 60秒 } } ); String text = resource.getString("message");
getBundleメソッドの第2引数で、ResourceBundle.Controlクラスをオーバーライドしたクラスのインスタンスを指定します。キャッシュ制御に関してオーバーライドするのは、getTimeToLiveメソッドです。このメソッドの戻り値がキャッシュ有効期間(ミリ秒)となるので、適切な値を返却するようにオーバーライドします。また、キャッシュを無効にする、無期限キャッシュにするには次の定数を返却するようにします。
定数名 | 内容 | 定義値 |
---|---|---|
ResourceBundle.Control.TTL_DONT_CACHE | キャッシュ無効 | -1 |
ResourceBundle.Control.TTL_NO_EXPIRATION_CONTROL | キャッシュ有効期間を無限 | -2 |