C'è un modo per specificare un valore di proprietà predefinito in Spring XML?


91

Stiamo utilizzando un PropertyPlaceholderConfigurer per utilizzare le proprietà java nella nostra configurazione Spring ( dettagli qui )

per esempio:

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

Vorremmo aggiungere una proprietà aggiuntiva, ma disponiamo di un sistema distribuito in cui le istanze esistenti potrebbero utilizzare tutte un valore predefinito. C'è un modo per evitare di aggiornare tutti i nostri file di proprietà, indicando un valore predefinito nella configurazione Spring per quando non è definito un valore di proprietà sovrascrivente?

Risposte:


14

Stai cercando il PropertyOverrideConfigurer documentato qui

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

PropertyOverrideConfigurer, un altro post-processore di bean factory, è simile a PropertyPlaceholderConfigurer, ma a differenza di quest'ultimo, le definizioni originali possono avere valori predefiniti o nessun valore per le proprietà del bean. Se un file Proprietà che sostituisce non ha una voce per una determinata proprietà del bean, viene utilizzata la definizione di contesto predefinita.


Qualcuno potrebbe spiegarmi cos'è un 18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA? Sono sicuro che tutti gli altri lo sappiano e sono solo stupido, ma nel caso ...
Sridhar Sarnobat

276

Spring 3 supporta la ${my.server.port:defaultValue}sintassi.


8
Solo per riferimento: SPR-4785
cubanacan

11
per me, sovrascrive sempre la proprietà con il valore predefinito, indipendentemente dal fatto che la proprietà sia definita o meno.
Ondrej Bozek

12
@OndrejBozek - (scusa se ho letto un vecchio post) Mi sono imbattuto in quello che potrebbe essere lo stesso problema, vedi Spring Framework issue [ jira.spring.io/browse/SPR-9989] . Quando sono coinvolti più configuratori di segnaposto, i valori predefiniti specificati con la notazione ":" vengono risolti solo dal primo configuratore di segnaposto nella catena. Quindi, se il primo configuratore non ha la proprietà, la proprietà sarà sempre impostata al valore predefinito, anche se i configuratori più in basso nella catena hanno la proprietà. Vedi [ stackoverflow.com/a/22452984/599609]
toni

1
sembra ${my.server.port:-defaultValue}anche dare lo stesso risultato, nota il " :-" in opposizione a " :".
Captain Man

2
È necessario aggiungere <context:property-placeholder/>perché funzioni, o aggiungere unPropertyPlaceholderConfigurer
shuckc

32

C'è una caratteristica poco conosciuta, che lo rende ancora migliore. È possibile utilizzare un valore predefinito configurabile invece di uno hardcoded, ecco un esempio:

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>

Per utilizzare l'impostazione predefinita pur essendo ancora in grado di sovrascrivere facilmente in seguito, eseguire questa operazione in config.properties:

timeout.myBean = ${timeout.default}

Questo ha funzionato per me ${timeout.myBean:${timeout.default}}. Ciò ha permesso che anche il mio predefinito fosse una variabile.
NewestStackOverflowUser



8

http://thiamteck.blogspot.com/2008/04/spring-propertyplaceholderconfigurer.html sottolinea che le "proprietà locali" definite sul bean stesso saranno considerate predefinite per essere sovrascritte dai valori letti dai file:

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

grazie, c'erano parole a riguardo in primavera javadoc, ma non sono riuscito a capire come farlo!
Guillaume

0

Inoltre trovo un'altra soluzione che funziona per me. Nel nostro progetto di primavera legacy utilizziamo questo metodo per dare ai nostri utenti la possibilità di utilizzare le proprie configurazioni:

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

E nel nostro codice per accedere a queste proprietà è necessario scrivere qualcosa del genere:

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

E se si verifica una situazione in cui è necessario aggiungere una nuova proprietà ma in questo momento non si desidera aggiungerla nella configurazione dell'utente di produzione, diventa molto velocemente un inferno quando è necessario applicare una patch a tutti i contesti di test o la tua applicazione fallirà avviare.

Per gestire questo problema puoi utilizzare la sintassi successiva per aggiungere un valore predefinito:

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

È stata una vera scoperta per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.