2011-10-02 72 views
1

我打算使用spring作爲我們企業應用程序的配置服務。spring context.refresh()和併發訪問

這部分在春季參考指南和其他博客中已有詳細記錄。基本上使用一個屬性文件和上下文: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或豆任何吸氣劑操作可能失敗,因爲IllegalStateException異常BeanCreationException

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

問題

  1. 是有可能的是,調用context.refresh()不影響其他併發呼叫
  2. 如果context.refresh()可以破壞的併發訪問應用程序環境是否有任何策略來避免這種情況發生。

您的指針將不勝感激。

回答

1

你可以做的是圍繞你的配置服務創建一些包裝,而不是刷新現有的上下文創建一個新的包裝。當新的準備就緒時,開始使用這個而不是舊的。

我不知道這是否是配置管理的最佳選擇,但該代碼看起來是這樣的(後來一個至少可以引進,沒有春天的依賴接口):

class MyConfig { 
    private ApplicationContext context; 

    public ApplicationContext getContext() { 
    return context; 
    } 

    public void refresh() { 
    context = new FileSystemXmlApplicationContext(..) 
    } 
}