Externalizar la configuración

A veces es conveniente externalizar la configuración de nuestras aplicaciones en lugar de almacenar en los ficheros de configuración toda la información sobre las conexiones a base de datos, etc. Imaginemos el siguiente escenario:

Tenemos una aplicación Spring con Maven integrada en un sistema de integración continua como Jenkins. Supongamos también que en nuestra organización disponemos de varios entornos (producción, calidad, desarrollo, etc.). Imaginemos finalmente que disponemos además de un repositorio de código corporativo como Nexus. En nuestra organización, hemos programado trabajos en Jenkins, para que por las noches, si existen cambios en nuestro repositorio de código, se empaquete nuestro proyecto y se suba al repositorio de código corporativo Nexus, de manera que si el resto de desarrolladores al día siguiente si tienen una referencia “abierta” al artefacto, tengan los últimos cambios. Además, hemos programado otros trabajos en Jenkins, para que despliegue las aplicaciones con las librerías actualizadas en los servidores de desarrollo y de calidad. Finalmente queremos lanzar las pruebas de integración de la aplicación en el servidor de calidad.

Si utilizamos Nexus para almacenar las aplicaciones web como ficheros .war, y hemos introducido la configuración de la conexión a base de datos en un fichero XML de Spring o en un fichero de propiedades dentro del propio War, no podremos tomar directamente la aplicación del Servidor Nexus y desplegarla tal cual en el servidor de calidad y el servidor de desarrollo, ya que cada uno de ellos tendrá sus propios datos de conexión a base de datos.  Si bien, ya vimos que con Maven se pueden definir perfiles y filtros para configurar nuestras aplicaciones, esta opción se me antoja un poco incómoda, ya que tendríamos que tener una versión configurada para cada entorno que queramos utilizar.

Spring proporciona mecanismos para externalizar la configuración que nos ayudan a resolver este tipo de situaciones utilizando alguno de estos mecanismos:

  • Property placeholder configurer → Sustituyen las propiedades de los marcadores de posición con los valores obtenidos de un archivo de propiedades externo.
  • Property override → Anulan los valores de las propiedades con los del archivo de propiedades externo.

Property placeholder configurer

Configurar un “placeholder configurer“, es tan simple como lo siguiente:

En el ejemplo anterior, se extraen las propiedades del sistema de archivos, también se podría haber utilizado “classpath:“. La configuración de la base de datos se puede definir ahora del siguiente modo:

Donde cada uno de estos marcadores (“${bd.driver}“, etc.) debe estar definido en el fichero de propiedades “bbdd.properties” de este modo:

También se puede hacer referencia con anotaciones @Value(“$(bd.driver)”) esto es similar al modo de trabajar con SpEL como ya vimos.

Lo normal, es que el departamento de desarrollo, no conozca los datos de conexión a la base de datos de producción. Podemos hacer referencia a un fichero de propiedades que estará presente en un determinado directorio de la máquina de producción, pero que no utilizaremos en desarrollo. Normalmente si utilizamos  “placeholder configurer” y no encuentra el fichero de propiedades se produce una excepción, pero podemos evitar esto configurando “ignore-resource-not-found” e “ignore-unresolvable”. Vamos a ver un ejemplo:

Bueno, creo que se explica sólo, en el caso de que no encuentre el fichero de propiedades o alguna propiedad del marcador de posición, se utilizarán los datos de configuración por defecto, que siguiendo con el ejemplo, estarían apuntando al servidor de desarrollo.

También se pueden utilizar variables del sistema, en lugar de archivos de propiedades. Podemos configurar en el elemento “property−placeholder” la propiedad “system-properties-mode“, con alguno de estos valores:

  • FALLBACK → Intenta resolver las variables de los marcadores de posición del archivo de propiedades, y en caso de que no se puedan resolver, utiliza las variables del sistema (este es el valor por defecto).
  • NEVER → Nunca se resuelven las variables de los marcadores de posición con las variables del sistema.
  • OVERRIDE → Se prefieren las variables del sistema, antes que las del archivo de propiedades

Property override

Con un anulador de propiedades, se pueden dejar las propiedades configuradas con los valores por defecto, ya que el anulador se encargará de “machacarlos”. La idea es definir en un archivo de propiedades valores “idBean.idPropiedad=valor” que se aplicarán en lugar de los valores definidos en el bean, por ejemplo

Si definimos en un archivo de propiedades, lo siguiente:

Dicho valor prevalecerá sobre lo que se configuró en el vean. Para que se active este comportamiento, ha que definir lo siguiente:

Para terminar, comentar que este elemento se puede configurar con el mismo conjunto de propiedades que “property-placeholder”.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *