Czy istnieje sposób na określenie domyślnej wartości właściwości w Spring XML?

92

Używamy PropertyPlaceholderConfigurer do używania właściwości java w naszej konfiguracji Spring ( szczegóły tutaj )

na przykład:

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

Chcielibyśmy dodać dodatkową właściwość, ale mamy system rozproszony, w którym wszystkie istniejące instancje mogłyby używać wartości domyślnej. Czy istnieje sposób, aby uniknąć aktualizowania wszystkich naszych plików właściwości, wskazując domyślną wartość w konfiguracji Spring, gdy nie ma zdefiniowanej zastępującej wartości właściwości?

Rog
źródło

Odpowiedzi:

14

Szukasz rozwiązania PropertyOverrideConfigurer udokumentowanego tutaj

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

PropertyOverrideConfigurer, kolejny postprocesor fabryki bean, jest podobny do PropertyPlaceholderConfigurer, ale w przeciwieństwie do tego ostatniego, oryginalne definicje mogą mieć wartości domyślne lub nie mieć żadnych wartości dla właściwości fasoli. Jeśli zastępujący plik Properties nie ma wpisu dla określonej właściwości komponentu bean, używana jest domyślna definicja kontekstu.

JoseK
źródło
Czy ktoś mógłby mi wyjaśnić, co to 18GerPD8fY4iTbNpC9hHNXNHyrDMampPLAjest? Jestem pewien, że wszyscy inni wiedzą i jestem po prostu głupi, ale na wszelki wypadek ...
Sridhar Sarnobat
277

Spring 3 obsługuje ${my.server.port:defaultValue}składnię.

leksykor
źródło
8
Tylko w celach informacyjnych: SPR-4785
kubański
11
dla mnie zawsze zastępuje właściwość wartością domyślną, bez względu na to, czy właściwość jest zdefiniowana, czy nie.
Ondrej Bozek
13
@OndrejBozek - (przepraszam, że wbijam stary post) Natknąłem się na coś, co może być tym samym problemem, zobacz problem Spring Framework [ jira.spring.io/browse/SPR-9989] . W przypadku wielu konfiguratorów symboli zastępczych wartości domyślne określone w notacji „:” są rozpoznawane tylko przez pierwszego konfiguratora zastępczego w łańcuchu. Jeśli więc pierwszy konfigurator nie ma właściwości, właściwość będzie zawsze ustawiana na wartość domyślną, nawet jeśli konfiguratorzy na dalszych etapach łańcucha mają tę właściwość. Zobacz [ stackoverflow.com/a/22452984/599609]
dźwięki
1
wydaje się, że ${my.server.port:-defaultValue}daje ten sam wynik, zwróć uwagę na „ :-” w przeciwieństwie do „ :”.
Captain Man,
2
Musisz dodać, <context:property-placeholder/>aby to zadziałało, lub dodaćPropertyPlaceholderConfigurer
shuckc
34

Jest mało znana funkcja, która czyni to jeszcze lepszym. Możesz użyć konfigurowalnej wartości domyślnej zamiast wartości zakodowanej na stałe, oto przykład:

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>

Aby użyć wartości domyślnej, jednocześnie mając możliwość łatwego zastąpienia później, zrób to w config.properties:

timeout.myBean = ${timeout.default}
Michael Böckling
źródło
To zadziałało dla mnie ${timeout.myBean:${timeout.default}}. Dzięki temu moja domyślna również była zmienną.
NewestStackOverflowUser
9

http://thiamteck.blogspot.com/2008/04/spring-propertyplaceholderconfigurer.html wskazuje, że „właściwości lokalne” zdefiniowane w samym ziarnie będą uważane za domyślne i nadpisane przez wartości odczytywane z plików:

<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> 
Robert Tupelo-Schneck
źródło
thx, były o tym słowa na wiosnę javadoc, ale nie byłem w stanie wymyślić, jak to zrobić!
Guillaume,
0

Znajduję również inne rozwiązanie, które działa dla mnie. W naszym starszym projekcie wiosennym używamy tej metody, aby dać naszym użytkownikom możliwość korzystania z tych własnych konfiguracji:

<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>

A w naszym kodzie, aby uzyskać dostęp do tych właściwości, należy napisać coś takiego:

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

A jeśli pojawi się sytuacja, kiedy musisz dodać nową właściwość, ale w tej chwili nie chcesz jej dodawać w konfiguracji użytkownika produkcyjnego, bardzo szybko staje się piekłem, gdy musisz załatać wszystkie konteksty testowe lub aplikacja zakończy się niepowodzeniem uruchomienie.

Aby poradzić sobie z tym problemem, możesz użyć następnej składni, aby dodać wartość domyślną:

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

To było dla mnie prawdziwe odkrycie.

Ilya
źródło