Ficheros .properties en Spring IoC


VERSIONES

  1. 25/07/2013 (Primera publicación)
  2. 29/09/2013:
    • Código publicado en GitHub

logo spring

 A la hora de utilizar el contenedor de Spring es una buena práctica separar la definición de los beans, parcial o totalmente realizada en ficheros XML, y los parámetros de configuración que utilizan esos beans como por ejemplo contraseñas o la ubicación de la base de datos. La ventaja de seguir este criterio es doble:

  • Los parámetros de configuración son fácilmente localizables y no están diseminados en los ficheros XML de Spring.
  • La configuración es fácilmente modificable por cualquier persona, como por ejemplo un administrador de sistemas, aunque no tenga conocimientos de Spring.

Lo habitual es definir los parámetros de configuración en ficheros de propiedades estándar de Java (.properties). Spring no sólo permite utilizar cómodamente este tipo de ficheros sino que el mecanismo a utilizar ha sido mejorado en Spring 3.1

Entorno de pruebas:

Requisitos: Conocimientos básicos de Spring IoC.

Proyecto para pruebas

Para las pruebas se usará un proyecto Maven consistente en un bean que se definirá en Spring y en el que se quiere utilizar un valor definido en un fichero .properties. Asimismo, se usará una clase Main.

En el pom.xml sólo se incluirá como dependencia spring-core en su última versión estable en el momento de escribir este artículo: 3.1.2.RELEASE. Cualquier incompatibilidad entre la versión de Spring y el código utilizado en este artículo se indicará expresamente.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0    	http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.danielme.blog.spring.properties</groupId>
	<artifactId>pruebaSpring-properties</artifactId>
	<version>1.0</version>
	<name>pruebaSpring-properties</name>

	<description>Ejemplo de utilización en Spring ioC de ficheros .properties.</description>
	
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.build.mainClass>com.danielme.blog.spring.properties.Main</project.build.mainClass>
	</properties>
	
	<developers>
		<developer>
			<id>dmedina</id>
			<name>Daniel Medina</name>
			<email>danielme_com@yahoo.com</email>
			<url>http://danielme.com</url>
			<roles>
				<role>developer</role>
			</roles>
		</developer>
	</developers>

	<licenses>
		<license>
			<name>El presente proyecto Maven es el código de ejemplo utilizado en el tutorial "Ficheros .properties en Spring IoC", 
			publicado con licencia Creative Commons Reconocimiento-NoComercial-CompartirIgual 3.0  Unported en la web 	
      "http://danielme.com"</name>
		</license>
	</licenses>

	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-jar-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<archive>
							<manifest>
								<addClasspath>true</addClasspath>
								<mainClass>${project.build.mainClass}</mainClass>
							</manifest>
						</archive>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>2.5.1</version>
					<configuration>
						<source>1.5</source>
						<target>1.5</target>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>exec-maven-plugin</artifactId>
					<version>1.2.1</version>
					<executions>
						<execution>
							<goals>
								<goal>java</goal>
							</goals>
						</execution>
					</executions>
					<configuration>
						<mainClass>${project.build.mainClass}</mainClass>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>

	<dependencies>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.1.2.RELEASE</version>
		</dependency>

	</dependencies>

</project>

El bean en el que se realizará la inyección:

package com.danielme.blog.spring.properties;

public class BeanSpring
{
	private Integer cantidad;
	
	private String usuario;

	public Integer getCantidad() 
	{
		return cantidad;
	}

	public void setCantidad(Integer cantidad) 
	{
		this.cantidad = cantidad;
	}

	public String getUsuario() 
	{
		return usuario;
	}

	public void setUsuario(String usuario) 
	{
		this.usuario = usuario;
	}	
}

y su definición en el springContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<bean id="beanSpring" class="com.danielme.blog.spring.properties.BeanSpring" />

</beans>

En la clase Main, se inicia el contexto de Spring y se recupera el bean

package com.danielme.blog.spring.properties;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * Ficheros .properties en Spring
 * 
 * @author danielme.com
 * 
 */
public class Main
{
	
	public static void main(String[] args) 
	{	
		//Se inicia programáticamente el contenedor de Spring y se obtiene el bean
  		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/springContext.xml");
  		 BeanSpring beanSpring = (BeanSpring) applicationContext.getBean("beanSpring");
             
                System.out.println("cantidad: " + beanSpring.getCantidad() + ", usuario: " + beanSpring.getUsuario()); 
	}		

}

Y por último, el fichero que justifica la redacción de este artículo (config.properties):

valor.usuario = usuario
valor.cantidad = 10

Si se quisiera utilizar el proyecto en Eclipse (es el IDE que siempre utilizo), tan sencillo como ejecutar el siguiente para generar un proyecto válido y luego importarlo:

$ mvn  eclipse:eclipse 

Método “tradicional” en XML

En primer lugar hay que “importar” el fichero .properties, y se puede hacer dos formas distintas

  1. Definiendo directamente un PropertyPlaceholderConfigurer que contendrá todos los .properties que queramos utilizar.

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    	<property name="location">
    		<value>classpath:config.properties</value>
    	</property>
    </bean>	
    
  2. Más fácil todavía con context:property-placeholder (OJO: sólo disponible a partir de Spring 2.5)
    <context:property-placeholder location="classpath:config.properties" />
    

    Para importar más de un fichero, simplemente se separan con comas. También se pueden importar todos.

    <context:property-placeholder location="classpath:*.properties" />
    

Ahora ya estamos en condiciones de inyectar los valores de los parámetros definidos en el config.properties

	<bean id="beanSpring" class="com.danielme.blog.spring.properties.BeanSpring">
		<property name="cantidad" value="${valor.cantidad}" />
		<property name="usuario" value="${valor.usuario}" />
	</bean>

Y listo. Ejecutamos nuestro Main (si no usamos un IDE se puede hacer desde la línea de comandos con “mvn clean package exec:java”) para comprobar que la inyección se ha realizado correctamente, y que incluso el número se ha inyectado en un Integer. No obstante, deberemos tener cuidado con estas conversiones ya que son susceptibles de provocar un hermoso java.lang.NumberFormatException.

Nota: se pueden importar .properties desde cualquier ubicación utilizando un location como “file:///C:\\configuraciones\\config.properties”. Esta posibilidad puede ser interesante a la hora de simplificar la configuración de aplicaciones web.

Con anotaciones

Si usamos Spring 3.1 se pueden inyectar los valores de los parámetros de los .properties simplemente utilizando la anotación @Value. En nuestro ejemplo, primero tendriamos que habilitar el “autowiring” mediante anotaciones en el springContext.xml y eliminar la inyección en beanSpring de las propiedades cantidad y usuario. Pero vamos a ir un paso más allá y realizar la definición del propio bean con anotaciones. Así pues, el fichero quedaría así:

	<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<!-- ruta en la que se buscarán los beans anotados -->
<context:component-scan base-package="com.danielme" />	

<context:property-placeholder location="classpath:config.properties" />
	
</beans>

Ahora tendremos que anotar el bean con @Service para que los instancie el contenedor y hacer la inyección mediante @Value. Esta inyección se va a hacer directamente en los atributos por lo que se puede prescindir de los setters si se crearon sólo para poder inyectar las dependencias.

package com.danielme.blog.spring.properties;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class BeanSpring
{
	@Value("${valor.cantidad}")
	private Integer cantidad;
	
	@Value("${valor.usuario}")
	private String usuario;

	public Integer getCantidad() 
	{
		return cantidad;
	}	

	public String getUsuario() 
	{
		return usuario;
	}	
	
}

Como vemos, gracias a Spring 3.1 podemos seguir reduciendo los XML en favor del uso de anotaciones siguiendo la tendencia impulsada por JEE y que poco a poco se va imponiendo en el mundo Spring.

En el caso de que estemos usando una versión anterior a Spring 3.1, se puede realizar también la inyección mediante autowired definiendo los valores de los properties como beans de Spring de la siguiente forma:

<bean id="cantidad" class="java.lang.Integer">
  <constructor-arg value="${valor.cantidad}"/>
</bean>

<bean id="usuario" class="java.lang.String">
  <constructor-arg value="${valor.usuario}"/>
</bean>

Es una solución menos elegante y limpia que la anterior pero nos permite seguir definiendo y configurando los beans con anotaciones en versiones anteriores de Spring que, por otra parte, tampoco podemos calificar como antiguas ya que Spring 3.1 se publicó en diciembre de 2011.

Código de ejemplo

El proyecto completo se encuentra en Github. Para más información sobre cómo utilizar GitHub, consultar este artículo.

2 Responses to Ficheros .properties en Spring IoC

  1. Daniel dice:

    Tengo el siguiente problema:

    Fichero Spring.xml:

    Conexion.java:

    @Service
    public class Conexion {

    @Value(“${mysql.url}”)
    private String url;

    @Value(“${mysql.user}”)
    private String user;

    @Value(“${mysql.password}”)
    private String password;

    @Value(“${mysql.driver}”)
    private String driver;

    public String getUrl() {
    return url;
    }
    public String getUser() {
    return user;
    }
    public String getPassword() {
    return password;
    }
    public String getDriver() {
    return driver;
    }
    }

    Como realizado la llamada por ejemplo al metodo getUrl() desde otra clase Java??

    • Gerardo Torreblanca Luna dice:

      Por que no utilizas un “datasource” lo defines en el archivo XML srpingContext, posteriormente realizas la inyeccion para que utilices en tus clases DAO, donde vayas a utilizar una conexcion, de esa manera Spring administra tus conexiones.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: