spring context.refresh()和并发访问

时间:2011-10-02 17:31:23

标签: spring configuration refresh applicationcontext

我打算将spring用作我们企业应用程序的配置服务。

这部分已在春季参考指南和其他博客中有详细记录。基本上使用属性文件和上下文: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>

但是在刷新上下文时,我发现由于 IllegalStateException BeanCreationException 。

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

问题

  1. 是否可能对context.refresh()的调用不会影响其他并发调用
  2. 如果context.refresh()可以破坏对应用程序上下文的并发访问,那么是否有任何策略可以避免这种情况发生。
  3. 您的指示将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以做的是在配置服务周围创建一些包装器,而不是刷新现有上下文创建一个新包装器。当新的准备就绪时,开始使用它而不是旧的。

我不确定这是否是配置管理的最佳选择,但代码看起来像这样(稍后可能至少会引入一个没有spring依赖的接口):

class MyConfig {
  private ApplicationContext context;

  public ApplicationContext getContext() {
    return context;
  }

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