%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ include file="/WEB-INF/jsp/include.jsp" %>
Vamos a poner en práctica los conceptos fundamentales del "Core Container" de Spring. Empezaremos creando el proyecto con Eclipse e instalando las librerías. Para simplificar vamos a empezar con un proyecto Java no Web (una sencilla aplicación "standalone") al que se añaden las librerías necesarias (ver la Introducción).
Los conceptos fundamentales de nuestro ejemplo son:
La estructura del proyecto es sencilla:
Las clases del dominio de problema tienen los típicos métodos set y get. Además tienen un método toString() que devuelve una cadena que representa los atributos de cada objeto. El cliente tiene unicamente un NIF:
package org.ejemplo;
public class Cliente {
protected String nif;
public Cliente( String nif ) {
this.nif = nif;
}
public Cliente() {}
public String getNif() {
return nif;
}
public void setNif(String nif) {
this.nif = nif;
}
public String toString() {
return "NIF: " + getNif();
}
}
La clase Producto:
package org.ejemplo;
import java.util.Enumeration;
import java.util.Properties;
public class Producto {
protected String codigo;
protected float precio;
protected Properties caracteristicas;
public Producto( String codigo, float precio ) {
setCodigo( codigo );
setPrecio( precio );
}
public Producto() {}
public String getCodigo() {
return codigo;
}
public void setCodigo(String codigo) {
this.codigo = codigo;
}
public float getPrecio() {
return precio;
}
public void setPrecio(float precio) {
this.precio = precio;
}
public Properties getCaracteristicas() {
return caracteristicas;
}
public void setCaracteristicas(Properties caracteristicas) {
this.caracteristicas = caracteristicas;
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append(" PRODUCTO. Código: " + getCodigo() + ". Precio: " + getPrecio());
//// Itero para recorrer la lista de propiedades
Enumeration it = caracteristicas.propertyNames();
while ( it.hasMoreElements()) {
String clave = (String) it.nextElement();
str.append("\n\t" + clave + ": " + caracteristicas.getProperty(clave));
}
return str.toString();
}
}
La Factura tiene que hacer referencia a un cliente y una lista de productos:
package org.ejemplo;
import java.util.*;
/******************************************************************************************
* La factura tiene un cliente y una lista de productos.
* Lanza excepción si no hay un cliente definido o si la lista de productos está vacia.
* Ver métodos set correspondientes.
*****************************************************************************************/
public class Factura {
protected Cliente cliente;
protected int numero;
protected List productos;
public Factura( Cliente cliente, int numero ) {
setNumero( numero );
setCliente( cliente );
}
public Factura( Cliente cliente, int numero, List productos ) {
setNumero( numero );
setCliente( cliente );
setProductos( productos );
}
public Cliente getCliente() {
return cliente;
}
public void setCliente(Cliente cliente) {
if (cliente == null || cliente.getNif() == null || cliente.getNif().length() == 0 )
throw new IllegalArgumentException( "No puede asignar a la factura " + numero + " un cliente no definido");
this.cliente = cliente;
}
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
public List getProductos() {
return productos;
}
public void setProductos(List productos) {
if (productos == null || productos.size() == 0 )
throw new IllegalArgumentException( "No puede asignar a la factura " + numero + " una lista vacia de productos");
this.productos = productos;
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append( "FACTURA Numero: " + getNumero() + ". " + cliente.toString());
//// Itero para recorrer la lista de productos
Iterator it = productos.iterator();
while ( it.hasNext()) {
Producto p = (Producto) it.next();
str.append("\n" + p.toString());
}
return str.toString();
}
}
En el método main() creamos el contenedor. Le pasamos como argumento el archivo XML en el que se definen los objetos y sus dependencias:
package org.ejemplo;
import org.springframework.beans.factory.xml.XmlBeanFactory;
//import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.ClassPathResource;;
/****************************************************************************************
* Clases del dominio: Factura, Producto y Cliente. La factura tiene asociado un cliente y
* una lista de productos.
* Son necesarias las librerias spring.jar y commons-logging-api.jar
***************************************************************************************/
public class Inicio {
public static void main(String[] args) {
try {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("org/xml/application-context.xml"));
// Otra forma: XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("c:/DOC/Java_Eclipse/spring05_main/src/org/xml/application-context.xml"));
Factura fac = (Factura) factory.getBean( "factura_alfa");
System.out.println( fac.toString());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Con el metodo getBean() se puede obtener un bean del contenedor. Como argumento se pasa el id del bean, definido en el archivo XML. En este ejemplo se obtiene la factura y se muestran por pantalla sus propiedades, obtenidas por medio del método toString().
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- Beans de aplicación -->
<beans>
<!-- Producto. La tercera propiedad es del tipo Properties y la manejamos con la etiqueta value -->
<bean id="prod_01" class="org.ejemplo.Producto">
<property name="codigo" value="FZX" />
<property name="precio" value="37.95" />
<property name="caracteristicas">
<value>
peso=12.34
tension=125
</value>
</property>
</bean>
<!-- Producto. Usamos el constructor.
La tercera propiedad es del tipo Properties y la manejamos con la etiqueta props -->
<bean id="prod_02" class="org.ejemplo.Producto">
<constructor-arg value="AK" />
<constructor-arg value="600" />
<property name="caracteristicas">
<props>
<prop key="capacidad">5</prop>
<prop key="caballos de vapor">130</prop>
<prop key="cilindrada">2200</prop>
</props>
</property>
</bean>
<!-- Cliente -->
<bean id="Pedro" class="org.ejemplo.Cliente">
<property name="nif" value="1111G" />
</bean>
<!-- Factura. Usamos el primer constructor para indicar el bean del tipo Cliente y el número.
Por medio de método set asignamos la lista de productos.
Nota: con el atributo type podriamos identificar el tipo. Ejemplo: type="java.lang.Integer".
-->
<bean id="factura_alfa" class="org.ejemplo.Factura">
<constructor-arg ref="Pedro"/>
<constructor-arg value="20080045" />
<property name="productos">
<list>
<ref bean="prod_01"/>
<ref bean="prod_02"/>
</list>
</property>
</bean>
</beans>
El resultado de ejecutar la aplicación es:
FACTURA Numero: 20080045. NIF: 1111G
PRODUCTO. Código: FZX. Precio: 37.95
tension: 125
peso: 12.34
PRODUCTO. Código: AK. Precio: 600.0
capacidad: 5
caballos de vapor: 130
cilindrada: 2200