Como configurar properties de Spring desde base de datos

Como configurar properties de Spring desde base de datos


Creo que la primera pregunta que todos nos hacemos al hacer uso de un PropertyPlaceholderConfigurer para remplazar valores de un fichero de configuración de Spring es ¿Y esto no se puede hacer por base de datos?.

La respuesta es sí y para hacerlo, podemos crear nuestro Properties que obtenga los valores desde desde una base de datos y provea a nuestro PropertyPlaceholderConfigurer de los valores a sustituir en nuestro applicationContext. Esto es una gran ventaja ya que solo requiere del reinicio del servidor para recargar la nueva configuración de nuestros beans de Spring.

Creamos un DAO que nos permita consultar todos los valores de nuestra tabla de configuración.

public class ConfigurationDao extends JdbcDaoSupport {

    /**
     * Retrieve all values in configuration table
     * 
     * @return
     */
    public Map<String, String> getAll() {

        Map configurations = new HashMap();

        List<Map<String, Object>> rows = getJdbcTemplate().queryForList("SELECT `key`, `value` FROM `configuration`");

        for (Map row : rows) {
            configurations.put(row.get("key").toString(), row.get("value").toString());
        }

        return configurations;

    }
}

Continuamos creando nuestra clase DatabaseConfigurationProperties que herede de Properties y reescribimos los métodos propertyNames, get, getProperty. Quedandonos algo así:

public class DatabaseConfigurationProperties extends Properties {

    private Map configurations;

    private ConfigurationDao configurationDao;

    @Override
    public Enumeration propertyNames() {
        // retrieve the list of availables configurations
        configurations = configurationDao.getAll();
        // return the names
        return Collections.enumeration(configurations.keySet());
    }

    @Override
    public synchronized Object get(Object key) {
        return configurations.get(key);
    }

    @Override
    public String getProperty(String key) {
        return (String) get(key);
    }

    // here setters...
}

Ya solo queda configurar nuestro nuevo properties y DAO en un PropertyPlaceholderConfigurer:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="properties">
        <bean class="com.nc.config.DatabaseConfigurationProperties">
            <property name="configurationDao">
                <bean class="com.nc.dao.ConfigurationDao">
                    <property name="dataSource" ref="dataSource" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

¿Facíl no? si no es así, aquí tienes el ejemplo completo https://github.com/makensi/examples/tree/master/databasepropertyconfigurer