Spring Framework Tutorial Parte 2: Instalación y ejemplo de inyección de dependencias

Spring Framework Logo

Spring Framework Logo

Hola a todos de nuevo, en este tutorial y en los siguientes comenzaremos a realizar ejemplos y codificar con el framework Spring. Para este tutorial y para los siguientes, usaremos el entorno de programación Eclipse aunque también podéis usar NetBeans sin problema.

                                       

Comenzaremos creando un proyecto nuevo, para evitar problemas con librerías y obtenerlas online, crearemos un proyecto Maven.

Nuevo proyecto Maven en Eclipse

Nuevo proyecto Maven en Eclipse

Para evitar usar archetypes, no olvideis marcar la opción “Create a simple project (skip archetype selection)”

Simple project, skype archetype selection in Eclipse

Simple project, skype archetype selection in Eclipse

Una vez creado el proyecto nos encontraremos con un proyecto vacío el cual tendrá una estructura básica.

Nos encontraremos con los siguientes directorios:

Package Explorer Maven Explorer

Package Explorer

  • /src/main/java directorio, contiene los archivos de código fuente
  • /src/test/java directorio que contiene todos los archivos  para las pruebas unitarias.
  • /src/main/resources directorio que contiene archivos de configuración o recursos estáticos.
  • /target directorio que contiene los archivos compilados y los archivos y empaquetados para distribución.
  • pom.xml llamado Project Objetc Model (POM). Es un fichero que contiene todos los proyectos (dependencias) relacionados con nuestro proyecto.

Para añadir el framework Spring tendremos que abrir el archivo pom.xml y añadir lo siguiente (abrirlo en modo texto):

<br />&lt;dependencies&gt;<br />    &lt;dependency&gt;<br />        &lt;groupId&gt;org.springframework&lt;/groupId&gt;<br />        &lt;artifactId&gt;spring-context&lt;/artifactId&gt;<br />        &lt;version&gt;4.0.2.RELEASE&lt;/version&gt;<br />    &lt;/dependency&gt;<br />&lt;/dependencies&gt;<br />

Con esto añadiremos en nuestro proyecto las dependencias necesarias para incorporar una serie de paquetes a nuestro proyecto, que son sin más, los necesarios para añadir todas las características de Spring.

Bien, ya hemos añadido las dependencias necesarias de Spring en nuestro proyecto, ahora abordaremos el siguiente punto de nuestro tutorial la inyección de dependencias con Spring.

Dependency Injection

Para ello tratemos primero el concepto y posteriormente un ejemplo de uso. El patrón de inyección de dependencias consiste en hacer que nuestras piezas de software sean independientes comunicándose únicamente a través de un interface. Esto implica muchas modificaciones en el código fuente como el uso de implementaciones, la eliminación de la instanciación de objetos mediante la instrucción new o la necesidad de un modo de configuración que indique que clases se instanciarán en el caso de solicitarlo.

Pero…¿qué beneficios aporta?

La instanciación de las dependencias inyectadas no se harán desde nuestro código fuente si no que se realizarán por reflexión o en nuestro caso a través de nuestro framework Spring. Esto significa que en nuestro código siempre trataremos contra una interfaz y para utilizar una instancia de una clase deberás invocar al repositorio de dependencias que se encargará de gestionar que objeto se desea instanciar y generarlo (y gestionarlo por nosotros). Esto es MUY importante en un software modular, imaginemos el ejemplo de los programas actuales que funcionan con plugins, ¿no necesitan recompilar todo el programa para volver a funcionar verdad? pues nosotros en nuestros programas podremos cambiar una parte de funcionalidad por otra sin necesidad de reprogramar las clases que lo van a utilizar, ¿genial no?.

Hay otros beneficios (que no vamos a tratar ahora) como facilidad en test de aplicaciones (gracias a la independencia anteriormente comentada), estandarización a la hora de programar (siempre trabajaremos igual, contra interfaces).

Ejemplo de uso

Vamos a crear un ejemplo en el cual tendremos tres clases (HelloWorld.java y Foo.java y Main.java) y un archivo de configuración (applicationContext.xml), veamos para qué nos servirán:

Fichero HelloWorld.java

Esta clase tendrá una dependencia sobre ‘Foo’ y es donde el contenedor de Spring inyectará la dependencia basada en constructor y establecido en applicationContext.xml.

<br />package spring.tutorial;<br />public class HelloWorld {<br />	/** Dependencia de la clase Foo. */<br />	private Foo foo;<br />	/** Un constructor en el cual Spring puede inyectar 'Foo' */<br />	public HelloWorld(Foo foo) {<br />		this.foo = foo;<br />	}<br />	public String toString() {<br />		return " HelloWorld! foo : \n " + foo;<br />	}<br />}<br />

Fichero Foo.java

Clase básica con un constructor el cual usará el contenedor Spring para crear una instancia e inyectarla sobre un objeto de HelloWorld.java

<br />package spring.tutorial;<br /><br />public class Foo {<br />private String name;<br />private String telephoneNumber;<br />private int age;<br /><br /> public Foo(String name, String telephoneNumber, int age){<br /> this.name = name;<br /> this.telephoneNumber = telephoneNumber;<br /> this.age = age;<br /> }<br /><br /> public Foo(String name, int age, String telephoneNumber) {<br />this.name = name;<br />this.age = age;<br />this.telephoneNumber = telephoneNumber;<br /> }<br /><br />public String toString(){<br />return " name : " + name+ " \n telephoneNumber : " + telephoneNumber + "\n age : " +age;<br />}<br />}

Fichero Main.java

Clase con un punto de entrada de ejecución, será la clase que ejecutemos. Tendremos llamadas a la clase applicationContext de Spring para generar nuestros bean y establecer llamadas sobre ellos.

<br />package spring.tutorial;<br /><br />import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.ClassPathXmlApplicationContext;<br /><br />public class Main {<br />	public static void main(String[] args) {<br />		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");<br />HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorldBean");<br />System.out.println(helloWorld);<br />	}<br />}<br />

Fichero applicationContext.xml

Fichero de configuración en el que se basará Spring para crear instancias de los bean y conocer/gestionar las dependencias entre clases. Si nuestro IDE no crea el fichero, deberemos crearlo en el directorio correspondiente, es decir en “/src/main/resources“. El contenido del fichero en nuestro caso será el siguiente:

<br />&lt;beans xmlns="http://www.springframework.org/schema/beans"<br />	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"<br />	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"<br />	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"<br />	xmlns:task="http://www.springframework.org/schema/task"<br />	xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"&gt;<br /><br />	&lt;bean id="helloWorldBean" class="spring.tutorial.HelloWorld"&gt;<br />		&lt;constructor-arg ref="fooBean" /&gt;<br />	&lt;/bean&gt;<br /><br />	&lt;bean id="fooBean" class="spring.tutorial.Foo"&gt;<br />		&lt;constructor-arg type="java.lang.String"&gt;<br />			&lt;value&gt;fooname&lt;/value&gt;<br />		&lt;/constructor-arg&gt;<br />		&lt;constructor-arg type="java.lang.String"&gt;<br />			&lt;value&gt;100&lt;/value&gt;<br />		&lt;/constructor-arg&gt;<br />		&lt;constructor-arg type="int"&gt;<br />			&lt;value&gt;25&lt;/value&gt;<br />		&lt;/constructor-arg&gt;<br />	&lt;/bean&gt;<br />&lt;/beans&gt;<br />

Como vemos en este xml, hay una primera referencia al bean helloWorldBean indicando dónde se sitúa la clase dentro de la estructura de paquetes y además ya indica que en el constructor existe un argumento que hace referencia al bean fooBean.
El bean fooBean se define debajo de igual forma, indicando que se dispone de con 3 parámetros: 2 Strings con valor “fooName” y “100” y un entero con el valor 25. No será necesario declarar los bean para las clases String o int pues son clases básicas (faltaría más). De esta forma el Contenedor de Spring, sabrá como interpretar la llamada de la clase Main.java cuando se invoque:

HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorldBean")

Simplemente buscará el constructor del bean helloWordBean, éste tiene como referencia al bean fooBean, el cual tiene parametrizado la construcción del objeto, así que Spring tan sólo seguirá las reglas de construcción. Como vemos en ningún momento se hace un new de ninguna clase y comprobamos que efectivamente en Foo ha sido inyectada en HelloWorld.

Si ejecutamos la clase Main.java comprobaremos en consola comprobaremos que la salida es:

<br />feb 27, 2014 4:18:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh<br />INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@60d70b42: startup date [Thu Feb 27 16:18:26 CET 2014]; root of context hierarchy<br />feb 27, 2014 4:18:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions<br />INFO: Loading XML bean definitions from class path resource [applicationContext.xml]<br /> HelloWorld! foo :<br />  name : fooname<br /> telephoneNumber : 100<br /> age : 25<br />

En el siguiente ejemplo comprobaremos cómo hacer una inyección de dependencias a través de setters y no a través de constructores. Para ello necesitaremos crear la clase:

Fichero Bar.java:
En esta clase podremos ver varias diferencias con HelloWorld.java, una de ellas es que no tiene constructor, tan sólo un setter de la dependencia que inyecta (Foo) y la anotación @Autowired. Cuando la Spring se encuentra una anotación @Autowired se utiliza los métodos setter, y realiza las llamadas autoconducidas para la creación del objeto.

<br />package spring.tutorial;<br /><br />import org.springframework.beans.factory.annotation.Autowired;<br /><br />public class Bar {<br />	private Foo foo;<br />	@Autowired<br />	public void setFoo(Foo foo) {<br />		this.foo = foo;<br />	}<br />	public String toString() {<br />		return "Bar! Foo : \n" + foo;<br />	}<br />}<br />

Para poder usar esta clase en el ejemplo, deberemos modificar por supuesto el fichero applicationContext.xml y añadir lo siguiente

<br />	&lt;context:annotation-config/&gt; &lt;!-- necesario para la anotación @Autowired --&gt;<br />		&lt;bean id="barBean" class="spring.tutorial.Bar"&gt;<br />		&lt;property name="foo"&gt;<br />			&lt;ref bean="fooBean" /&gt;<br />		&lt;/property&gt;<br />	&lt;/bean&gt;<br />

Y por último modificamos el archivo Main.java para usar la nueva clase Bar.java a través del Contenedor de Spring, veamos cómo:

<br />package spring.tutorial;<br /><br />import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.ClassPathXmlApplicationContext;<br /><br />public class Main {<br />	public static void main(String[] args) {<br />		ApplicationContext context = new ClassPathXmlApplicationContext(<br />				"applicationContext.xml");<br />		Bar bar = (Bar) context.getBean("barBean");<br />		System.out.println(bar);<br />	}<br />}<br />

Si realizamos una compilación del proyecto y ejecutamos, el resultado será el mismo, pero en este caso la inyección de dependencia está basado en un setter con una anotación de @Autowired.

Para descargar el proyecto de ejemplo podremos hacerlo desde desde aquí: Mega , ta sólo tendréis que descomprimir el fichero e importar un proyecto Maven desde Eclipse o abrir un proyecto Maven desde NetBeans.

Gracias a todos por la lectura, ¡compartid y cualquier comentario es bienvenido!

Anuncios

Una respuesta a “Spring Framework Tutorial Parte 2: Instalación y ejemplo de inyección de dependencias

  1. Muy buen tutorial para entrar en el mundo de Spring!

    Lo unico que modifiqué en el Main, es la linea en que llama al application-context y me quedó asi:
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
    “application-context.xml”);
    Para despues poder agregar el context.close()

    Saludos!!!

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 )

Google+ photo

Estás comentando usando tu cuenta de Google+. 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 )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.