WebSphere и PropertyPlaceholderConfigurer

Я большой пользователь свойств (с 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, а затем просто выполнить перезагрузку...

У кого-нибудь есть идеи о том, как я мог бы сделать такую ​​продвигаемую сборку? Я уже определил конфигурацию JNDI для источников данных/почты Java/и т. д.

Спасибо!


person Andries Inzé    schedule 11.08.2009    source источник


Ответы (5)


Мы решили эту проблему, используя расширение файла свойств для каждой среды (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.

person Robin    schedule 11.08.2009

Одна из потенциальных проблем заключается в том, что вы жестко задаете расположение файла свойств. Вы можете указать расположение файла свойств в качестве ресурса 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>

Таким образом, вы можете указать разные имена файлов для разных сред с помощью консоли WAS в Ресурсы > URL-адреса > URL-адреса, создав ресурс с JNDI-именем "url/config" и указав его на правильный файл (file:///your/ путь/к/свойствам).

В качестве альтернативного решения, если вы хотите управлять отдельными свойствами через консоль, вместо использования PropertyPlaceholderConfigurer вы можете использовать jee:jndi-lookup для получения значений из env-записей web.xml (которыми вы можете управлять с помощью консоли WAS). ). См. этот ответ

person beny23    schedule 08.12.2009

Если конфигурация находится в файле EAR, то я не знаю простого способа распространить изменения без бэкдор-читов или повторного развертывания приложения.

Я думаю, что конфигурация, особенно та, которая изменяется при продвижении приложения, не должна быть в приложении.

Один подход описан здесь Кейсом Боцумом,

Обратите внимание, что вы можете распространять файлы, которые не являются частью какого-либо конкретного приложения, на узлы с помощью стандартной синхронизации WebSphere.

Другой вариант — использовать базу данных для конфигурации. В наши дни вставить XML в БД, такую ​​как DB2, не очень сложно.

person djna    schedule 11.08.2009

Добавление URL-ресурса, который указывает на ваши файлы конфигурации, на ваши серверы websphere, а затем просмотр его в вашем приложении — это жизнеспособный способ. Затем вы можете настроить URL-адрес так, чтобы он указывал на центральное место, где управляются все файлы конфигурации - если вы используете svn и ваш svn имеет доступ только для чтения, вы даже можете напрямую читать их из svn (через http).

Spring имеет некоторые встроенные средства для этого, и это также означает, что вы можете установить приоритеты для различных файлов конфигурации.

Для получения дополнительной информации см. >как-отличить-тестовые-и-рабочие-свойства-в-приложении

person Michael Wiles    schedule 11.08.2009

Способ, которым я справился с этим, состоит в том, чтобы использовать значения свойств в JVM, но затем ссылаться на них в переменной WebSphere, которая определена на уровне кластера или ячейки. Например, скажем, вы хотите, чтобы значение с именем value1 было установлено в param1 в вашей конфигурации spring, вы должны сделать следующее:

<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");
        }

Затем из конфигурации веб-сферы, если вы создадите переменную JVM и свяжете ее с переменной WebSphere, вам нужно будет только изменить переменную WebSphere, и она автоматически обновит все переменные JVM на каждой машине.

Для этого создайте переменную JVM с именем:

параметр1

со значением ${webspherevar.param1}

Затем создайте переменную WebSphere с именем:

webspherevar.param1

Это содержит любое значение, которое вам нужно поместить в него. Это позволяет вам не пересылать значения для каждой среды, вместо этого их можно загрузить в среду и просто использовать.

Надеюсь, это поможет.

person mransley    schedule 24.08.2009