1

エンタープライズ アプリケーションの構成サービスとして spring を使用する予定です。

この部分は、スプリング リファレンス ガイドや他のブログで十分に文書化されています。基本的に、プロパティ ファイルと context:property-placeholder を使用して、アプリケーションで使用される Bean に値をインスタンス化および設定する予定です。

プロパティ ファイルが変更される場合があり、その場合、変更された値を Bean に反映させたいと考えています。ApplicationContext.refresh() が Bean とその構成値を更新する方法であることを理解しています。ApplicationContext.refresh() は魅力的に機能しました。

<context:property-override location="file:///d:/work/nano-coder/quickhacks/src/main/resources/myproperties.properties"/>

<bean id="myconfig" class="org.nanocoder.quickhacks.config.MyPropertyBean">
    <property name="cacheSize" value="${registry.ehcache.size}"/>
    <property name="httpHostName" value="${url.httpHostName}"/>
    <property name="httpsHostName" value="${url.httpsHostName}"/>
    <property name="imageServers">
        <list>
          <value>${url.imageserver1}</value>
          <value>${url.imageserver2}</value>
          <value>${url.imageserver3}</value>
        </list>
    </property>

</bean>

ただし、コンテキストが更新されているときに、 ApplicationContext.getBean() への同時呼び出しまたは Bean での getter 操作がIllegalStateExceptionまたはBeanCreationExceptionにより失敗する可能性があることがわかりました。

value = context.getBean("myconfig", MyPropertyBean.class).getHttpHostName();

質問

  1. context.refresh() への呼び出しが他の同時呼び出しに影響を与えない可能性はありますか
  2. context.refresh() がアプリケーションコンテキストへの同時アクセスを妨害する可能性がある場合、これを回避するための戦略はありますか?

あなたのポインタは大歓迎です。

4

1 に答える 1

1

できることは、構成サービスの周りにラッパーを作成し、既存のコンテキストを更新する代わりに新しいコンテキストを作成することです。新しいものが準備できたら、古いものの代わりにこれを使い始めます。

これが構成管理に最適な選択であるかどうかはわかりませんが、コードは次のようになります (後で少なくとも、Spring 依存性のないインターフェイスを導入できます)。

class MyConfig {
  private ApplicationContext context;

  public ApplicationContext getContext() {
    return context;
  }

  public void refresh() {
    context = new FileSystemXmlApplicationContext(..)
  }
}
于 2011-10-03T11:29:05.990 に答える