Несколько файлов свойств в Spring 3.0
Я работаю над проектом с несколькими отдельными модулями, каждый со своими собственными файлами свойств контекста приложения. Я хочу, чтобы иметь возможность загружать все эти свойства, чтобы они могли использоваться для разрешения места размещения с помощью Spring.
Предыдущие вопросы упомянули об этом, и есть хорошее сообщение в блоге здесь, в котором описывается, как использовать PropertyPlaceholderConfigurer в каждом контексте, заказывать их по приоритету и установите ignoreUnresolveablePlaceholders в true, чтобы эти файлы свойств могли перекрестно ссылаться друг на друга, не взорвав.
Однако это не решает мою проблему, так как я также хочу иметь возможность использовать свойства, которые я загружаю для некоторого произвольного разрешения заполнителя (из некоторых файлов ямлов, которые я разбор). Для этого требуется использовать PropertyPlaceholderHelper, для чего объект Properties является аргументом.
Насколько я могу судить, потенциальные решения:
1) Слейте весь файл свойств в один из свойств bean. Затем это можно использовать для создания PropertyPlaceholderConfigurer (для Spring внутреннего разрешения заполнителя) и используется с PropertyPlaceholderHelper (для моего собственного разрешения заполнителя)
2) Каким-то образом настройте PropertyPlaceholderHelper для использования набора свойств и их иерархического расположения, проводимого PropertyPlaceholderConfigurers, если я пойду дальше и следую советам этого сообщения в блоге.
К сожалению, я не могу понять, как это сделать. Любая помощь будет принята с благодарностью!
PS Похоже, что Spring 3.1 будет большой помощью здесь... к сожалению, мы еще не готовы двигаться к нему, поэтому мне все еще нужно решение, чтобы переправить меня!
**** ИЗМЕНИТЬ ****
Спасибо за ответы до сих пор. Это хорошие ответы, но, к сожалению, мне это не поможет, потому что (и извиняюсь, что не упоминал об этом ранее) мы в настоящее время находимся в процессе ветки основных модулей нашего проекта от неосновных модулей. Это означает, что основные модули и их контекст приложения не могут жестко закодировать имена файлов свойств. Разочарование, сканирование классов Spring, по-видимому, нарушено, поэтому подстановочные знаки типа "classpath *: *. Properties" работают только при создании отдельных модулей, а не в проекте верхнего уровня (я считаю, что это известная проблема).
Вопрос заключается в том, как объединить файлы свойств, определенные в неосновных модулях, в существующие файлы свойств, определенные в основных модулях. В настоящий момент я продвигаюсь с помощью BeanPostProcessor - мне просто интересно, есть ли более простой/более элегантный способ сделать это?
Спасибо
Ответы
Ответ 1
Вы можете легко собрать несколько файлов свойств в один bean:
<bean id="allProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath*:default.properties</value>
<value>classpath*:overrides.properties</value>
<value>file:${APP_HOME}/**/*.properties</value>
</list>
</property>
</bean>
В этом конкретном примере будут собраны все параметры default.properties, overrides.properties в файлах классов и файлах свойств в вашем APP_HOME. Теперь вы можете обратиться к этому bean от ProperyPlaceholderConfigurer или к своему пользовательскому постпроцессору.
Ответ 2
Следующий фрагмент кода должен начать работу
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="corePlaceHolder">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="searchSystemEnvironment" value="true"/>
<property name="locations">
<list>
<value>classpath*:config/*/config1/*.properties</value>
<value>classpath*:config/*/config2/*.properties</value>
<value>classpath*:config/*/config3/*.properties</value>
<value>classpath*:custom.properties</value>
</list>
</property>
</bean>
Вы можете хранить файлы свойств в следующей иерархии, чтобы убедиться, что config доступен из класса classpath
config
config1
a.properties
config2
b.properties
config3
c.properties
custom.properties
Ответ 3
Это все, что вам нужно сделать:
<context:property-placeholder location="first.properties" order="0" ignore-unresolvable="true"/>
<context:property-placeholder location="second.properties" order="0" ignore-unresolvable="true"/>
<context:property-placeholder location="empty.properties" order="1"/>
Проблема проста: если свойство-placeholder не имеет значения для определенного свойства, оно выдает исключение, даже если присутствует другой объект-заполнитель.
В решении используется order
, чтобы узнать, что является последним property-placeholder
, и устанавливает ignore-unresolvable="true"
для всех остальных, так что каждый property-placeholder
имеет возможность предоставить значение. В многомодульных проектах последний property-placeholder
может быть пустым или обеспечивать отказоустойчивые значения по умолчанию.
Примечание. Если вы установите для параметра all-placeholder значение ignore-unresolvable="true"
Spring, вы просто передадите то, что вы написали, не выбрасывая исключение. Если вы, конечно, ожидаете, что это будет нечто иное, чем String
, вы, безусловно, получите перехват, например java.lang.NumberFormatException: For input string: "${something}"
во время преобразования формата.
Примечание: будет использоваться только первый (один с самым низким order
) property-placeholder
со значением для конкретного свойства. Если вы хотите переопределить свойства, используйте больший диапазон order
, чем 0
и 1
или property-override
.
Протестировано с помощью Spring 3.2.1, но все упомянутые свойства существуют в версии 3.0. См. JavaDoc свойства PropertyPlaceholderConfigurer