Property Configurer

Comment remplacer dynamiquement les propriétés d'un bean Spring ?



Remplacement de propriétés

La technique traditionnelle pour externaliser les valeurs de propriétés d'un bean est d'utiliser le post-processeur PropertyPlaceholderConfigurer.

<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driver"><value>${jdbc.driver}</value></property>
  <property name="url"><value>${jdbc.url}</value></property>
  <property name="user"><value>${jdbc.user}</value></property>
  <property name="password"><value>${jdbc.password}</value></property>
</bean>

<bean id="placeholder" 
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="location"><value>jdbc.properties</value></property>
</bean>
# Fichier jdbc.properties
jdbc.driver=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost
jdbc.user=sa
jdbc.password=

Redéfinition de propriétés

Il est possible de faire une manipulation similaire, sans la logique de placeholder, mais en écrasant les valeurs définies dans le bean, avec le PropertyOverrideConfigurer

<bean id="dataSource"
      class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
  <property name="driverClassName" value="org.hsqldb.jdbcDriverx" />
  <property name="url" value="jdbc:hsqldb:hsql://localhost/XXX" />
  <property name="username" value="sax" />
  <property name="password" value="xxx" />
</bean>

<bean id="placeholder"
      class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
  <property name="location">
    <value>jdbc.properties</value>
  </property>
</bean>

Les propriétés enregistrées dans le fichier font référence aux propriétés du bean sur la construction beanName.propertyName :

# Fichier jdbc.properties
dataSource.driverClassName=org.hsqldb.jdbcDriver
dataSource.url=jdbc:hsqldb:hsql://localhost
dataSource.username=sa
dataSource.password=

Chargement personnalisé de propriétés

Dans les deux cas, il est possible d'aller plus loin dans la personnalisation des propriétés, en utilisant un bean personnel de propriétés.

<bean id="dsProperties"
      class="fr.sewatech.university.utils.DatasourceProperties" />

<bean id="placeholder"
      class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
  <property name="properties" ref="dsProperties"/>
</bean>

Dans ce cas, les propriétés ne sont plus forcément stockées en fichier, mais sont gérée dans le constructeur de notre classe DatasourceProperties.

// Fichier DatasourceProperties.java
package fr.sewatech.university.utils;

import java.util.Properties;

public class DatasourceProperties extends Properties {

  private static final long serialVersionUID = -2672136808054763735L;
  
  public DatasourceProperties() {
    this.put("datasource.driverClassName", "org.hsqldb.jdbcDriver");
    this.put("datasource.url", "jdbc:hsqldb:hsql://localhost");
    this.put("datasource.username", "sa");
    this.put("datasource.password", "");
  }
}

Dans l'exemple ci-dessus, les propriétés sont codées en dur dans le constructeur ; il est évident que nous pouvons remplacer cette portion de code par l'accès à un bean injecté, ou )ar un accès direct à une base de données.