1

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

这部分在 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 操作都可能由于IllegalStateExceptionBeanCreationException而失败。

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

问题

  1. 对 context.refresh() 的调用是否可能不会影响其他并发调用
  2. 如果 context.refresh() 可以中断对应用程序上下文的并发访问,是否有任何策略可以避免这种情况发生。

您的指点将不胜感激。

4

1 回答 1

1

你可以做的是围绕你的配置服务创建一些包装器,而不是刷新现有的上下文创建一个新的。当新的准备好后,开始使用它而不是旧的。

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

class MyConfig {
  private ApplicationContext context;

  public ApplicationContext getContext() {
    return context;
  }

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