Gibt es eine Möglichkeit, einen Standardeigenschaftswert in Spring XML anzugeben?

91

Wir verwenden einen PropertyPlaceholderConfigurer , um Java-Eigenschaften in unserer Spring-Konfiguration zu verwenden ( Details hier ).

z.B:

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

Wir möchten eine zusätzliche Eigenschaft hinzufügen, haben jedoch ein verteiltes System, in dem vorhandene Instanzen alle einen Standardwert verwenden können. Gibt es eine Möglichkeit, das Aktualisieren aller unserer Eigenschaftendateien zu vermeiden, indem in der Spring-Konfiguration ein Standardwert angegeben wird, wenn kein übergeordneter Eigenschaftswert definiert ist?

Rog
quelle

Antworten:

14

Suchen Sie den hier dokumentierten PropertyOverrideConfigurer?

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

Der PropertyOverrideConfigurer, ein weiterer Bean-Factory-Postprozessor, ähnelt dem PropertyPlaceholderConfigurer, aber im Gegensatz zu letzterem können die ursprünglichen Definitionen Standardwerte oder gar keine Werte für Bean-Eigenschaften haben. Wenn eine überschreibende Eigenschaftendatei keinen Eintrag für eine bestimmte Bean-Eigenschaft enthält, wird die Standardkontextdefinition verwendet.

JoseK
quelle
Könnte mir jemand erklären, was ein 18GerPD8fY4iTbNpC9hHNXNHyrDMampPLAist? Ich bin sicher, dass alle anderen es wissen und ich bin nur dumm, aber nur für den Fall ...
Sridhar Sarnobat
276

Spring 3 unterstützt die ${my.server.port:defaultValue}Syntax.

Lexicore
quelle
8
Nur als Referenz: SPR-4785
Cubanacan
11
Für mich überschreibt es immer die Eigenschaft mit dem Standardwert, unabhängig davon, ob die Eigenschaft definiert ist oder nicht.
Ondrej Bozek
12
@OndrejBozek - (Entschuldigung, dass ich einen alten Beitrag gestoßen habe) Ich bin auf das gleiche Problem gestoßen , siehe Spring Framework-Problem [ jira.spring.io/browse/SPR-9989] . Wenn mehrere Platzhalterkonfiguratoren beteiligt sind, werden die mit der Notation ':' angegebenen Standardwerte nur vom ersten Platzhalterkonfigurator in der Kette aufgelöst. Wenn der erste Konfigurator nicht über die Eigenschaft verfügt, wird die Eigenschaft immer auf den Standardwert gesetzt, auch wenn Konfiguratoren weiter unten in der Kette über die Eigenschaft verfügen. Siehe [ stackoverflow.com/a/22452984/599609]
Töne
1
es scheint ${my.server.port:-defaultValue}auch das gleiche Ergebnis zu geben, beachten Sie das " :-" im Gegensatz zu " :".
Captain Man
2
Sie müssen hinzufügen, <context:property-placeholder/>damit dies funktioniert, oder einPropertyPlaceholderConfigurer
shuckc
32

Es gibt eine wenig bekannte Funktion, die dies noch besser macht. Sie können einen konfigurierbaren Standardwert anstelle eines fest codierten Werts verwenden. Hier ein Beispiel:

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>

Führen Sie dies in config.properties aus, um die Standardeinstellung zu verwenden und sie später problemlos überschreiben zu können:

timeout.myBean = ${timeout.default}
Michael Böckling
quelle
Das hat bei mir funktioniert ${timeout.myBean:${timeout.default}}. Dadurch konnte mein Standard auch eine Variable sein.
NewestStackOverflowUser
10

Dem Standardwert kann ein :nach dem Eigenschaftsschlüssel folgender Wert folgen , z

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

Oder im Java-Code:

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

Sehen:

Übrigens ist der Elvis-Operator nur in Spring Expression Language (SpEL) verfügbar,
z. B.: Https://stackoverflow.com/a/37706167/537554

Ryenus
quelle
8

http://thiamteck.blogspot.com/2008/04/spring-propertyplaceholderconfigurer.html weist darauf hin, dass "lokale Eigenschaften", die auf der Bean selbst definiert sind, als Standardwerte betrachtet werden, die durch aus Dateien gelesene Werte überschrieben werden:

<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
quelle
thx, es gab wörter darüber im frühling javadoc, aber ich konnte nicht herausfinden, wie es geht!
Guillaume
0

Ich finde auch eine andere Lösung, die für mich funktioniert. In unserem Legacy-Frühjahrsprojekt verwenden wir diese Methode, um unseren Benutzern die Möglichkeit zu geben, diese eigenen Konfigurationen zu verwenden:

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

Und in unseren Code, um auf diese Eigenschaften zuzugreifen, müssen Sie Folgendes schreiben:

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

Und wenn eine Situation auftritt, in der Sie eine neue Eigenschaft hinzufügen müssen, diese aber derzeit nicht in der Produktionsbenutzerkonfiguration hinzufügen möchten, wird es sehr schnell zur Hölle, wenn Sie alle Ihre Testkontexte patchen müssen oder Ihre Anwendung fehlschlägt Anfang.

Um dieses Problem zu beheben, können Sie mit der nächsten Syntax einen Standardwert hinzufügen:

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

Es war eine echte Entdeckung für mich.

Ilya
quelle