【问题标题】:WebSphere and PropertyPlaceholderConfigurerWebSphere 和 PropertyPlaceholderConfigurer
【发布时间】:2009-08-11 15:01:22
【问题描述】:

我是属性(使用 PropertyPlaceholderConfigurer)的大用户,因为我可以使我的应用程序尽可能“动态”。几乎所有的常量都是这样定义的。无论如何,我目前正在定义一个default.properties,它随默认 WAR 一起提供。

在其他环境(验收/生产)中,我需要覆盖配置。我这样做如下:

<bean id="propertyManager"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:com/company/default.properties</value>
                <value>file:${COMPANY_PROPERTIES_LOCATION}\kbo-select-settings.properties</value>
            </list>
        </property>
    </bean>

这意味着我可以为每个环境使用可升级的构建。

但是,我确实不喜欢无法从 WebSphere 内部更改任何属性的事实。相反,我必须访问每台服务器(我们有 8 个集群)并相应地更改属性。如果我可以从 WebSphere 内部更改这些内容并在之后执行重新启动,那将更加用户友好...

任何人都知道我该如何做这样一个可推广的构建?我已经为 datasources/java mail/etc 定义了 JNDI 配置。

谢谢!

【问题讨论】:

    标签: java spring websphere


    【解决方案1】:

    我们通过在每个环境(local、dev、int、tst ...)的属性文件上使用扩展名解决了这个问题,每个文件都包含这些环境的特定值。唯一需要添加的是服务器上的 VM 参数以设置 -Druntime.env=X。

    您在配置文件中的查找将如下所示

    <bean id="propertyManager"
     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
           <list>
              <value>classpath:com/company/default.properties.${runtime.env}</value>
              <value>file:${COMPANY_PROPERTIES_LOCATION}\kbo-select-settings.properties</value>
            </list>
        </property>
     </bean>
    

    当然,这仅在您拥有相当静态的环境时才有效,因为它仍然不适合在运行时更改它,但它确实使应用程序的推广变得非常简单。如果您希望能够在不重新部署应用程序的情况下更改值,则必须将它们存储在应用程序之外,您似乎已经为 kbo-select-settings.properties

    【讨论】:

      【解决方案2】:

      一个潜在的问题是您正在硬编码属性文件的位置。您可以将属性文件的位置指定为 JNDI 资源并使用类路径中指定的默认值:

      <!--  try to lookup the configuration from a URL, if that doesn't work, fall back to the properties on the classpath -->
      <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          <property name="location">
              <bean class="org.springframework.core.io.UrlResource">
                  <constructor-arg>
                      <jee:jndi-lookup 
                          jndi-name="url/config" 
                          default-value="file:///tmp" /> <!--  dummy default value ensures that the URL lookup doesn't fall over if the JNDI resource isn't defined -->
                  </constructor-arg>
              </bean>
          </property>
          <property name="properties">
              <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                  <property name="locations">
                      <list>
                          <value>classpath:com/company/default.properties</value>
                      </list>
                  </property>
              </bean>
          </property>
          <property name="ignoreResourceNotFound" value="true"/> 
      </bean>
      

      这样,您可以通过使用 JNDI 名称“url/config”创建资源并将其指向正确的文件(file:// /your/path/to/properties)。

      作为替代解决方案,如果您想通过控制台管理单个属性,您可以使用 jee:jndi-lookup 从 web.xml env-entries(您可以使用管理WAS 控制台)。见this answer

      【讨论】:

        【解决方案3】:

        如果配置在 EAR 文件中,那么我知道没有简单的方法可以在没有后门作弊或重新部署应用程序的情况下传播更改。

        我认为该配置,尤其是在您推广应用程序时发生变化的配置不应应用程序中。

        Keys Botzum 描述了一种方法here

        请注意,您实际上可以使用标准 WebSphere 同步将不属于任何特定应用程序的文件传播到节点。

        另一种选择是使用数据库进行配置。如今,将 XML 放入 DB2 等数据库并不难。

        【讨论】:

          【解决方案4】:

          将指向您的配置文件的 URL 资源添加到您的 websphere 服务器,然后在您的应用程序中查找它是一种可行的方法。然后,您可以将 url 配置为指向管理所有配置文件的中心位置 - 如果您使用 svn 并且您的 svn 具有只读访问权限,您甚至可以直接从 svn 读取它们(通过 http)。

          Spring为此提供了一些内置功能,这也意味着您可以优先考虑各种配置文件。

          更多信息请查看how-to-differentiate-between-test-and-production-properties-in-an-application

          【讨论】:

            【解决方案5】:

            我处理这个问题的方法是在 JVM 上使用属性值,然后将它们引用到在集群或单元级别定义的 WebSphere 变量。例如,假设您希望在 spring 配置中的 param1 中设置一个名为 value1 的值,您可以执行以下操作:

            <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
            

            然后像下面这样引用变量:

            <bean id="id" class="com.blah.class">
                    <property name="value1" value="${param1}" />
            </bean>
            

            然后在您的测试中,您可以按如下方式设置测试:

            /**
                 * @see org.springframework.test.AbstractSingleSpringContextTests#prepareApplicationContext(org.springframework.context.support.GenericApplicationContext)
                 */
                @Override
                protected void prepareApplicationContext(GenericApplicationContext context) {
                    System.setProperty("param1", "myvalue");
                    }
            

            然后在 websphere 配置中,如果您创建一个 JVM 变量并将其链接到 WebSphere 变量,您只需更改 WebSphere 变量,它会自动更新每台机器上的所有 JVM 变量。

            为此,创建一个名为:

            参数1

            值为 ${webspherevar.param1}

            然后创建一个名为的 WebSphere 变量:

            webspherevar.param1

            其中包含您需要放入的任何值。这使您不必为每个环境提供值,而是可以将它们加载到环境中并直接使用。

            我希望这会有所帮助。

            【讨论】:

              猜你喜欢
              • 2014-05-04
              • 1970-01-01
              • 2011-11-24
              • 2012-02-13
              • 2011-11-20
              • 2012-02-18
              • 2017-02-26
              • 1970-01-01
              • 2014-10-18
              相关资源
              最近更新 更多