Есть ли способ указать значение свойства по умолчанию в Spring XML?

92

Мы используем PropertyPlaceholderConfigurer для использования свойств java в нашей конфигурации Spring ( подробности здесь )

например:

<foo name="port">
  <value>${my.server.port}</value>
</foo>

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

Rog
источник

Ответы:

14

Вы ищете PropertyOverrideConfigurer, описанный здесь?

http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-overrideconfigurer

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

JoseK
источник
Может ли кто-нибудь объяснить мне, что 18GerPD8fY4iTbNpC9hHNXNHyrDMampPLAтакое? Я уверен, что все знают, и я просто глуп, но на всякий случай ...
Шридхар Сарнобат
277

Spring 3 поддерживает ${my.server.port:defaultValue}синтаксис.

лексикор
источник
8
Для справки: SPR-4785
cubanacan
11
для меня он всегда заменяет свойство значением по умолчанию, независимо от того, определено свойство или нет.
Ondrej Bozek
13
@OndrejBozek - (извините, что ударил старый пост) Я столкнулся с той же проблемой, см. Проблема Spring Framework [ jira.spring.io/browse/SPR-9989] . Если задействовано несколько конфигураторов-заполнителей, значения по умолчанию, указанные в нотации ':', разрешаются только первым конфигуратором-заполнителем в цепочке. Таким образом, если у первого конфигуратора нет свойства, для свойства всегда будет установлено значение по умолчанию, даже если конфигураторы, расположенные дальше по цепочке, имеют свойство. См. [ Stackoverflow.com/a/22452984/599609]
звуки
1
похоже, ${my.server.port:-defaultValue}также дает тот же результат, обратите внимание на " :-" вместо " :".
Captain Man
2
Вам нужно добавить, <context:property-placeholder/>чтобы это работало, или добавитьPropertyPlaceholderConfigurer
shuckc 01
34

Есть малоизвестная функция, которая делает это еще лучше. Вы можете использовать настраиваемое значение по умолчанию вместо жестко запрограммированного, вот пример:

config.properties:

timeout.default=30
timeout.myBean=60

context.xml:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location">
        <value>config.properties</value>
    </property>
</bean>

<bean id="myBean" class="Test">
    <property name="timeout" value="${timeout.myBean:${timeout.default}}" />
</bean>

Чтобы использовать значение по умолчанию, но при этом можно было легко изменить его позже, сделайте это в config.properties:

timeout.myBean = ${timeout.default}
Михаэль Бёклинг
источник
Это сработало для меня ${timeout.myBean:${timeout.default}}. Это позволило мне по умолчанию также быть переменной.
NewestStackOverflowUser
11

За значением по умолчанию может следовать символ :после ключа свойства, например

<property name="port" value="${my.server.port:8080}" />

Или в java-коде:

@Value("${my.server.port:8080}")
private String myServerPort;

Увидеть:

Кстати, оператор Элвиса доступен только в Spring Expression Language (SpEL),
например: https://stackoverflow.com/a/37706167/537554

ryenus
источник
9

http://thiamteck.blogspot.com/2008/04/spring-propertyplaceholderconfigurer.html указывает, что "локальные свойства", определенные в самом компоненте, будут считаться значениями по умолчанию, которые будут заменены значениями, считанными из файлов:

<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  <property name="location"><value>my_config.properties</value></property>  
  <property name="properties">  
    <props>  
      <prop key="entry.1">123</prop>  
    </props>  
  </property>  
</bean> 
Роберт Тупело-Шнек
источник
спасибо, в весеннем javadoc об этом писали, но я не мог понять, как это сделать!
Guillaume
0

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

<bean id="appUserProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="ignoreResourceNotFound" value="false"/>
    <property name="locations">
        <list>
            <value>file:./conf/user.properties</value>
        </list>
    </property>
</bean>

И в нашем коде для доступа к этим свойствам нужно написать что-то вроде этого:

@Value("#{appUserProperties.userProperty}")
private String userProperty

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

Чтобы решить эту проблему, вы можете использовать следующий синтаксис, чтобы добавить значение по умолчанию:

@Value("#{appUserProperties.get('userProperty')?:'default value'}")
private String userProperty

Для меня это было настоящим открытием.

Илья
источник