Spring Framework 000 - Instanciar Beans con Spring Framework

De ChuWiki

Introducción a Spring Core[editar]

Spring Core es una la base de Spring Framework. Una vez que hayamos escrito nuestras clases Java, podemos usar Spring Core para instanciar, inicializar y hacer que unas clases vean a otras. Toda esta información sobre qué queremos se guarda en un fichero XML y Spring Core se encarga automáticamente de instanciar, inicializar las clases y pasar unas a otras, de forma que puedan llamarse entre sí.

Vamos a hacer aquí un pequeño ejemplo tonto con Spring Core. Tienes el código completo en PruebaBeanContainer.java. Para montar y arrancar el ejemplo sin necesidad de bajarte las dependencia a mano, puedes usar Maven con este fichero pom.xml

Una clase para instanciar con Spring[editar]

Para este ejemplo sencillo, usaremos Java Beans o POJO (Plain Old Java Object). Son simplemente clases que tienen una serie de atributos, un constructor sin parámetros y métodos set() y get() para acceder a esos atributos. Por ejemplo la siguiente

package com.chuidiang.pruebas.spring;

import java.util.Date;

/** 
 * Bean con los atributos correspondientes a los campos de la tabla de base
 * de datos.
 * @author chuidiang
 */
public class Persona {
	int id;
	String nombre;
	Date fechaNacimiento;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getNombre() {
		return nombre;
	}
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	public Date getFechaNacimiento() {
		return fechaNacimiento;
	}
	public void setFechaNacimiento(Date fechaNacimiento) {
		this.fechaNacimiento = fechaNacimiento;
	}
	
	/** Para poder escribir el bean en pantalla de forma rápida */
	public String toString()
	{
		return ""+id+" "+nombre+" "+fechaNacimiento;
	}
}

Simplemente tienes tres atributos: un entero id, un String nombre y un java.util.Date fechaNacimiento. No ponemos Date porque complicaría el ejemplo innecesariamente, ya que Spring Core necesitará convertir este Date a un String y viceversa. Esta conversión no está soportada por defecto y deberíamos implementarla.

El fichero XML de configuración de Spring[editar]

Ahora creamos el fichero XML que leerá Srping Core para saber qué tiene que hacer. Este fichero XML, para este solo bean, es bastante tonto y lo llamaremos beans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

  <bean id="Juan" class="com.chuidiang.pruebas.spring.Persona">
    <property name="id" value="1"/>
    <property name="nombre" value="Juan"/>
    <property name="fechaNacimiento" value="11/12/1943"/>
  </bean>
  
  <bean id="Pedro" class="com.chuidiang.pruebas.spring.Persona">
    <property name="id" value="2"/>
    <property name="nombre" value="Pedro"/>
    <property name="fechaNacimiento" value="1/1/1999"/>
  </bean>
 
</beans>

Cada tag <bean> se convertirá en una instancia de la clase. El id nos permite identificar esa instancia concreta. El class nos dice qué clase es el bean. Con este fichero de ejemplo, se harán dos new de com.chuidiang.pruebas.spring.Persona. A uno lo identificaremos como Juan y al otro como Pedro. Los atributos de cada uno de ellos se rellenarán con los <property> que se indican dentro de cada tag <bean>

Puedes ver que las fechaNacimiento se rellenan con un String del estilo 11/12/1943. Spring Core es capaz de hacer, por defecto, la conversión de ese String a una fecha, siempre que entienda el formato del String. En nuestro caso, puede ser MM/dd/YYYY (ojo, el mes va delante). Hay formas de configurar Spring para que entienda el formato de fecha que deseemos.

Lanzando el contexto de Spring[editar]

El código java que tenemos que hacer para lanzar Spring Core y obtener estos dos beans es el siguiente

package com.chuidiang.pruebas.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

public class PruebaBeanContainer {

	public static void main(String[] args) {
		Resource resource = new FileSystemResource("beans.xml");
		BeanFactory factory = new XmlBeanFactory(resource);
		System.out.println(factory.getBean("Juan"));
		System.out.println(factory.getBean("Pedro"));
	}
}

Primero instanciamos un FileSystemResource pasándole el fichero beans.xml. Por supuesto, deberemos poner el path si no está en el directorio actual de ejecución.

Luego instanciamos la factoría de beans XmlBeanFactory. Ya está todo listo. Ahora sólo queda trabajar.

Pedimos con factory.getBean(), usando como parámetro el id del bean en el fichero XML y escribimos en pantalla ambos beans, "Juan" y "Pedro".

Aquí hemos usado FileSystemResource porque el fichero beans.xml es un fichero normal en nuestro disco duro. Otra opción que este fichero esté dentro de nuestra aplicación empaquetada en un fichero jar. En ese caso, debemos usar ClassPathXmlApplicationContext y usar como path la ubicación del fichero dentro del fichero jar. El código sería

BeanFactory factory2 = new ClassPathXmlApplicationContext("beans.xml");
System.out.println(factory2.getBean("Juan"));
System.out.println(factory2.getBean("Pedro"));

Usar el constructor[editar]

Si a Persona le ponemos un constructor con parámetros

    public Persona(){
        // Constructor sin parametros.
    }

    public Persona(int id, String nombre, Date fechaNacimiento){
        this.id = id;
        this.nombre = nombre;
        this.fechaNacimiento = fechaNacimiento;
    }

podemos utilizarlo desde el fichero de configuración de Spring.

    <bean id="Antonio" class="com.chuidiang.pruebas.spring.Persona">
        <constructor-arg value="3"/>
        <constructor-arg value="Antonio"/>
        <constructor-arg value="3/13/2001"/>
    </bean>

Símplemente usamos <constructor-arg> poniendo como value lo que queramos. Únicamente, el orden en que pongamos estos argumentos debe ser el mismo con el que están declarados en el constructor. Aunque podemos también poner el nombre del parámetro y entonces podríamos ponerlo en cualquier orden

    <bean id="Antonio" class="com.chuidiang.pruebas.spring.Persona">
        <constructor-arg name="fechaNacimiento" value="3/13/2001"/>
        <constructor-arg name="nombre" value="Antonio"/>
        <constructor-arg name="id" value="3"/>
    </bean>