私は次のようなクラスを持っています:
public class Configurator {
private static Configurator INSTANCE = null;
private int maxRange = 1;
// many other properties; each property has a default value
private static synchronized Configurator getInstance() {
if(INSTANCE == null)
return new Configurator();
return INSTANCE;
}
public static int getMaxRange() {
getInstance().maxRange;
}
public static void setMaxRange(int range) {
getInstance().maxRange = range;
}
// Getters and setters for all properties follow this pattern
}
これは、アプリの起動時に設定できるグローバル構成オブジェクトとして機能し、プロジェクト全体で数十のクラスによって使用されます。
// Called at app startup to configure everything
public class AppRunner {
Configurator.setMaxRange(30);
}
// Example of Configurator being used by another class
public class WidgetFactory {
public void doSomething() {
if(Configurator.getMaxRange() < 50)
// do A
else
// do B
}
}
このコードをSpringプロジェクトにインポートして、Sprinig XML(beans)を構成しようとしています。私の推測では、単一のConfigurator
Beanを次のように定義できます(または類似の何か)。
<bean id="configurator" class="com.me.myapp.Configurator" scope="singleton">
<property name="maxRange" value="30"/>
<!-- etc., for all properties -->
</bean>
このようにして、WidgetFactory#doSomething
が実行されるとき、SpringはConfigurator
クラスをすでにロードし、事前に構成しています。
scope="singleton"
を設定するのは正しいですか、それとも問題ありませんか?静的プロパティを正しく設定していますか?ここで私がやるべきことや考慮すべきことは他にありますか?前もって感謝します。
Beanはデフォルトでシングルトンです。あなたは春のウェブサイトを介してこの/詳細情報を見つけることができます。
新しいConfiguratorをgetInstanceでインスタンス化しないでください。スプリングロードされたBeanを参照しないため、重大な問題が発生する可能性があります。このBeanを配線し、そのままにしておくことができます。配線したため、nullにはなりません(それがプログラムの場合、初期化に失敗します)。
はい。グローバルなものが必要な場合は、シングルトンスコープが適切なオプションです。ここで言及する価値のあるものは次のとおりです。
ちなみに、これはスレッドセーフではありません:
if(INSTANCE == null)
return new Configurator();
return INSTANCE;
}
これは次のようになります。
private static Configurator INSTANCE = new Configurator();
(熱心な初期化)
private static volatile Singleton _instance = null;
(volatileキーワードによる遅延初期化)
Java=はメモリを割り当ててインスタンスを作成します。これはアトミックではありませんが、2つのステップで行われ、スレッドスケジューラによって干渉される可能性があります。
http://regrecall.blogspot.de/2012/05/Java-singleton-pattern-thread-safe.html も参照してください。