Existe-t-il un moyen de spécifier une valeur de propriété par défaut dans Spring XML?

91

Nous utilisons un PropertyPlaceholderConfigurer pour utiliser les propriétés java dans notre configuration Spring ( détails ici )

par exemple:

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

Nous aimerions ajouter une propriété supplémentaire, mais disposer d'un système distribué où les instances existantes pourraient toutes utiliser une valeur par défaut. Existe-t-il un moyen d'éviter de mettre à jour tous nos fichiers de propriétés, en indiquant une valeur par défaut dans la configuration Spring lorsque aucune valeur de propriété de remplacement n'est définie?

Rog
la source

Réponses:

14

Recherchez-vous le PropertyOverrideConfigurer documenté ici

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

Le PropertyOverrideConfigurer, un autre post-processeur d'usine de bean, est similaire au PropertyPlaceholderConfigurer, mais contrairement à ce dernier, les définitions d'origine peuvent avoir des valeurs par défaut ou aucune valeur du tout pour les propriétés du bean. Si un fichier de propriétés de remplacement n'a pas d'entrée pour une certaine propriété de bean, la définition de contexte par défaut est utilisée.

JoseK
la source
Quelqu'un pourrait-il m'expliquer ce qu'est un 18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA? Je suis sûr que tout le monde le sait et je suis juste stupide, mais juste au cas où ...
Sridhar Sarnobat
276

Spring 3 prend en charge la ${my.server.port:defaultValue}syntaxe.

Lexicore
la source
8
Juste pour la référence: SPR-4785
cubanacan
11
pour moi, il remplace toujours la propriété avec la valeur par défaut, peu importe si la propriété est définie ou non.
Ondrej Bozek
12
@OndrejBozek - (désolé de modifier un ancien post) J'ai rencontré ce qui pourrait être le même problème, voir le numéro de Spring Framework [ jira.spring.io/browse/SPR-9989] . Lorsque plusieurs configurateurs d'espace réservé sont impliqués, les valeurs par défaut spécifiées avec la notation «:» ne sont résolues que par le premier configurateur d'espace réservé de la chaîne. Donc, si le premier configurateur n'a pas la propriété, la propriété sera toujours définie sur la valeur par défaut, même si les configurateurs plus bas dans la chaîne ont la propriété. Voir [ stackoverflow.com/a/22452984/599609]
ton
1
il semble ${my.server.port:-defaultValue}aussi donner le même résultat, notez le " :-" par opposition à " :".
Captain Man
2
Vous devez ajouter <context:property-placeholder/>pour que cela fonctionne, ou ajouter unPropertyPlaceholderConfigurer
shuckc
32

Il existe une fonctionnalité peu connue, ce qui rend cela encore meilleur. Vous pouvez utiliser une valeur par défaut configurable au lieu d'une valeur codée en dur, voici un exemple:

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>

Pour utiliser la valeur par défaut tout en étant capable de remplacer facilement plus tard, procédez comme suit dans config.properties:

timeout.myBean = ${timeout.default}
Michael Böckling
la source
Cela a fonctionné pour moi ${timeout.myBean:${timeout.default}}. Cela a permis à ma valeur par défaut d'être également une variable.
DateStackOverflowUser
11

La valeur par défaut peut être suivie d'un :après la clé de propriété, par exemple

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

Ou en code java:

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

Voir:

BTW, l' opérateur Elvis est uniquement disponible dans Spring Expression Language (SpEL),
par exemple: https://stackoverflow.com/a/37706167/537554

Ryenus
la source
8

http://thiamteck.blogspot.com/2008/04/spring-propertyplaceholderconfigurer.html indique que les "propriétés locales" définies sur le bean lui-même seront considérées comme des valeurs par défaut remplacées par les valeurs lues à partir des fichiers:

<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
la source
thx, il y avait des mots à ce sujet au printemps javadoc, mais je n'ai pas été en mesure de comprendre comment faire!
Guillaume
0

Aussi je trouve une autre solution qui fonctionne pour moi. Dans notre projet de printemps hérité, nous utilisons cette méthode pour donner à nos utilisateurs la possibilité d'utiliser ces propres configurations:

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

Et dans notre code pour accéder à ces propriétés, il faut écrire quelque chose comme ça:

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

Et si une situation se présente lorsque vous devez ajouter une nouvelle propriété mais que pour l'instant vous ne voulez pas l'ajouter dans la configuration utilisateur de production, cela devient très vite un enfer lorsque vous devez patcher tous vos contextes de test ou votre application échouera Commencez.

Pour gérer ce problème, vous pouvez utiliser la syntaxe suivante pour ajouter une valeur par défaut:

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

C'était une vraie découverte pour moi.

Il y a
la source