Artículos recomendados antes de leer este:

No voy a entrar en detalles teóricos sobre Spring ya que en los dos últimos artículos hablamos sobre Inyección de Dependencias y Contenedores. Mencionare los conceptos adicionales necesarios para conocer mejor Spring framework. 

Spring básicamente permite hacer uso del paradigma de IoC(Inversión del Control) que ya habíamos visto. En el artículo anterior vimos una lista de pasos para usar un contenedor en nuestra aplicación. Son los siguientes:

  1. Indicamos un punto de arranque para nuestra aplicación, un lanzador.
  2. Este lanzador carga o inicia el contenedor.
  3. El contenedor carga la configuración de nuestros objetos y dependencias.
  4. Le pedimos al contenedor que nos proporcione nuestra aplicación.

Usaremos las mismas clases del artículo anterior, Office, Printer, DotMatrixPrinter y Main.

 

Usando el API de Spring

El core de Spring a través de la interface BeanFactory proporciona todas las características de IoC e Inyección de Dependencias. La clase principal que implementa esta interface es DefaultListableBeanFactory. Esta sera nuestro “Container”.

Spring no solo es un simple contenedor para inyectar dependencias, también ofrece otras características y servicios como transaccionalidad, AOP, eventos, soporte i18n, contextos y mas. Para esto Spring extiende el BeanFactory con la interface ApplicationContext de la que hablaremos pronto.

Spring framework posee muchos modulos, pero aqui solo vamos a usar dos. El modulo core y el modulo beans. Las dependencias maven necesarias solo son:

1
2
3
4
5
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-beans</artifactId>
   <version>4.0.5.RELEASE</version>
</dependency>


Manualmente se necesita agregar al proyecto los siguientes jars:

  • spring-core-4.0.5.RELEASE.jar
  • spring-beans-4.0.5.RELEASE.jar
  • commons-logging-1.1.3.jar

 

Paso 1, punto de arranque

Nuestro punto de inicio o lanzador será un clase Main igual que el ejemplo del artículo anterior.

Paso 2, el lanzador inicia el contenedor

Aquí usamos la clase de Spring que indicamos anteriormente, DefaultListableBeanFactory.

1
DefaultListableBeanFactory container = new DefaultListableBeanFactory();

Paso 3, cargar la configuración al contenedor

Aquí tenemos varios sub-pasos, primero debemos especificar nuestra configuración. Spring permite esto a través de un archivo de configuración xml o a través de anotaciones. Usaremos el xml y lo llamaremos my-beans.xml. En Spring nuestros objetos se conocen como Beans.

1
2
3
4
5
6
7
8
9
10
11
12
<?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.xsd">

   <bean id="myDotMatrixPrinter" class="com.test.spc.DotMatrixPrinter" />

   <bean id="office" class="com.test.spc.Office">
      <constructor-arg ref="myDotMatrixPrinter" />
   </bean>

</beans>


El elemento <bean ...> permite definir mis objetos. Ahora cargamos nuestro xml y se lo pasamos al contenedor. Usaremos clases de Spring para ayudarnos. Primero usamos un cargador de recursos con la interface ResourceLoader. Luego un lector de xml con XmlBeanDefinitionReader.

1
2
3
4
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("classpath:my-beans.xml");
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(container);
beanDefinitionReader.loadBeanDefinitions(resource);


Paso 4, pedimos nuestra aplicación(bean) al contenedor

1
2
3
Office officeBean = container.getBean(Office.class);
officeBean.setMessageToPrint("Hola mundo!!");
officeBean.print();


Uniendo todo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//1.
public class Main {

   public static void main(String[] args) {

      //2. 
      DefaultListableBeanFactory container = new DefaultListableBeanFactory();

      //3.
      ResourceLoader resourceLoader = new DefaultResourceLoader();
      Resource resource = resourceLoader.getResource("classpath:my-beans.xml");

      XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(container);
      beanDefinitionReader.loadBeanDefinitions(resource);

      //4.
      Office officeBean = container.getBean(Office.class);
      Office officeBean2 = container.getBean(Office.class);
      officeBean.setMessageToPrint("Hola mundo!!");
      officeBean.print();
   }
}


Detalles de configuración del xml

Los atributos importantes en el elemento <bean> son class que permite especificar la clase y el id que se usa como identificador y permite referenciar el bean en todo el xml. En esta configuración usamos la inyección por constructor con el elemento <constructor-arg> y con el atributo ref definimos cual id de bean es la dependencia. También podemos inyectar dependencias por un método setter. De esta manera debemos usar el atributo <property> así:

1
<property name="printer" ref="myDotMatrix" />


Nuestra clase Office debe definir un método setter:

1
2
3
4
5
6
7
8
9
10
public class Office {

   private Printer printer;

   public void setPrinter(Printer printer) {
      this.printer = printer;
   }

   //mas codigo...
}


Scope

Otro punto importante para entender es que Spring cada vez que le pides un bean te retorna el mismo objeto ya que por defecto crea una sola instancia de cada bean, es lo que se conoce como scope singleton. Si queremos una instancia diferente cada vez que hacemos getBean() definimos el bean como scope prototype:

1
<bean id="office" class="com.test.spc.Office" scope="prototype">...


Historia de Spring

Spring fue lanzado en 2004 y nació como una alternativa a las primeras versiones de Enterprise JavaBeans(EJB). Se define como un contenedor liviano no intrusivo ya que nuestras clases no necesitan extender ni implementar nada del framework. Cosa que si era necesaria con EJB. Y el nombre de los beans de Spring viene de Enterprise JavaBeans.

Código Fuente

Código Fuente en GitHub


Franky Villadiego

Volando hacia el desarrollo productivo!