Возможно ли иметь несколько PropertyPlaceHolderConfigurer в моем applicationContext?

Мне нужно загрузить конкретный файл applicationContext.xml в соответствии с заданным системным свойством. Он сам загружает файл с фактической конфигурацией. Поэтому мне нужно 2 PropertyPlaceHolderConfigurer, которое разрешает системный параметр, а другой - в реальной конфигурации.

Любые идеи, как это сделать?

Ответ 1

Да, вы можете сделать больше одного. Обязательно установите ignoreUnresolvablePlaceholders, чтобы в первом случае игнорировать любые заполнители, которые он не может решить.

<bean id="ppConfig1" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="ignoreUnresolvablePlaceholders" value="true"/>
   <property name="locations">
    <list>
             <value>classpath*:/my.properties</value>
    </list>
  </property>
</bean>

<bean id="ppConfig2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="ignoreUnresolvablePlaceholders" value="false"/>
   <property name="locations">
    <list>
             <value>classpath*:/myOther.properties</value>
    </list>
  </property>
</bean>

В зависимости от вашего приложения вы должны исследовать systemPropertiesMode, он позволяет загружать свойства из файла, но позволяет системным свойствам переопределять значения в файле свойств, если они установлены.

Ответ 2

Остерегайтесь - может быть ошибка, связанная с несколькими конфигураторами. Подробнее см. http://jira.spring.io/browse/SPR-5719.

Я не могу заставить несколько работать локально... но я еще не обвиняю никого, кроме себя.

Ответ 3

Другим решением является использование свойства placeholderPrefix PropertyPlaceholderConfigurer. Вы указываете его для второго (третьего, четвертого...) конфигуратора, а затем префикс всех соответствующих заполнителей, поэтому конфликт не будет.

<bean id="mySecondConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="classpath:/myprops.properties" 
        p:placeholderPrefix="myprefix-"/>

<bean class="com.mycompany.MyClass" p:myprop="${myprefix-value.from.myprops}"/>

Ответ 4

Вы не можете сделать это напрямую, и эта проблема JIRA из Spring объясняет, почему (посмотрите комментарий от Chris Beams для подробного объяснения):

https://jira.springsource.org/browse/SPR-6428

Однако он предоставляет обходное решение с использованием Spring 3.1 или новее, которое должно использовать класс PropertySourcesPlaceholderConfigurer вместо класса PropertyPlaceholderConfigurer.

Вы можете загрузить проект на основе Maven, который демонстрирует проблему и решение из проблем фреймворка Spring github:

https://github.com/SpringSource/spring-framework-issues

Найдите номер проблемы, SPR-6428, в загруженных проектах.

Ответ 5

Со своей стороны, играя с PropertyPlaceholderConfigurer оба свойства:

  • порядок (должен быть ниже для первого доступа/проанализированного PPC)
  • ignoreUnresolvablePlaceholders ( "false" для первого доступа/проанализированного PPC, "true" для следующего)

  • а также дать 2 разных идентификатора (ов) для обоих PPC (чтобы не перезаписывать другой)

отлично работает

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

Ответ 6

У нас есть следующий подход:

<util:properties id="defaultProperties">
    <prop key="stand.name">DEV</prop>
    <prop key="host">localhost</prop>
</util:properties>
<context:property-placeholder 
    location="file:${app.properties.path:app.properties}" 
    properties-ref="defaultProperties"/>

Системное свойство app.properties.path может использоваться для переопределения пути к файлу конфигурации.

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