22oct/097

If(”spring”==”primavera”){?¿?¿?¿}

Print This Post

Si no estabais seguros de la temática de este blog, algunos me llamareis ¡loco!, otros os estaréis preguntando qué es eso de Spring y porqué es tan famoso, otros pensaréis que ya está otro pesao vendiéndonos el framework este. De cualquier modo, lo que busco en esta entrada es introducir este framework y emplear el blog en dar a conocer mi experiencia personal en el uso del Core de Spring. Como algunos de vosotros ya conoceréis, Spring posee multitud de aplicaciones y puesto que no puedo explicarlas todas en una entrada, para eso está este blog. Tiempo al tiempo...

La primera versión de Spring fue escrita por Rod Jonhson, quien lo lanzó primero con la publicación de su libro "Expert One-on-One Java EE Design and Development", basado en las mejores prácticas aceptadas. Tras la publicación, sus lectores le solicitaron que el código que acompañaba al libro fuera liberado bajo una licencia Open Source. A raíz de eso, se formó un pequeño equipo de desarrolladores que esperaba trabajar en extender el framework, y se creó el primer proyecto en Sourceforge en febrero de 2003. Después de trabajar en su desarrollo durante más de un año, la primera versión (1.0) fue lanzada en marzo de 2004, momento a partir del cual Spring ganó mucha popularidad en la comunidad Java, debido en parte al uso de Javadoc y de una documentación de referencia por encima del promedio de un proyecto de código abierto.

Spring Framework hizo que aquellas técnicas que resultaban desconocidas para la mayoría de programadores se volvieran populares en un periodo muy corto de tiempo, cuyo ejemplo más notable fue la inversión de control. En el año 2004, Spring disfrutó de unas altísimas tasas de adopción y al ofrecer su propio framework de programación orientada a aspectos (aspect-oriented programming, AOP) consiguió hacer más popular su paradigma de programación en la comunidad Java. Actualmente springsource ha sido adquirido por el líder en soluciones de virtualización VMWare (+ info)

El principal objetivo del framework es FACILITAR EL DESARROLLO DE SOFTWARE (TANTO JAVA COMO .NET). A lo largo de todas las liberaciones del proyecto, se han ido añadiendo módulos: Mensajería (JMS), Integración (ESB), Acceso a Datos (JDBC, ADO .Net, Hibernate), todos ellos con el propósito de reducir complejidad al desarrollo, permitiendo así que los desarrolladores dediquen sus esfuerzos a lo que realmente es necesario y “no reinventen la rueda”.

Actualmente la versión (java) estable del framework es la 2.5.6 y contiene los siguientes módulos:

spring-overview

Como primera aproximación al mundo de spring, explicaremos el corazón de Spring: La inversión de control (IoC). Según Wikipedia, la Definición de IoC es la siguiente:

La inversión de control es un método de programación en el que el flujo de ejecución de un programa se invierte respecto a los métodos de programación tradicionales, en los que la interacción se expresa de forma imperativa haciendo llamadas a procedimientos o funciones. Tradicionalmente el programador especifica la secuencia de decisiones y procedimientos que pueden darse durante el ciclo de vida de un programa mediante llamadas a funciones. En su lugar, en la inversión de control se especifican respuestas deseadas a sucesos o solicitudes de datos concretas, dejando que algún tipo de entidad o arquitectura externa lleve a cabo las acciones de control que se requieran en el orden necesario y para el conjunto de sucesos que tengan que ocurrir. En los comienzos de la programación, los programas eran lineales y monolíticos. El flujo de ejecución era simple y predecible, ejecutándose línea tras línea. Aparecieron dos conceptos que revolucionaron la programación: la modularidad y la reutilización de los componentes: se crean bibliotecas de componentes reutilizables. El flujo se complica, saltando de componente a componente, y aparece un nuevo problema: la dependencia (acoplamiento) entre nuestros componentes.
El problema se empieza a considerar lo suficientemente importante como para definir nuevos conceptos en el diseño:

  • Inversión de Control (IoC)
  • Inyección de Dependencias (Dependency Injection, DI)

El flujo habitual se da cuando es el código del usuario quien invoca a un procedimiento de una biblioteca, la inversión de control sucede cuando es la biblioteca la que invoca el código del usuario. Típicamente sucede cuando la biblioteca es la que implementa las estructuras de alto nivel y es el código del usuario el que implementa las tareas de bajo nivel.

La utilización de interfaces y la aparición de los frameworks ha popularizado este término. De hecho es el concepto central del Framework de Spring, ya que implementa un "Contenedor" que se encarga de gestionar las instancias (así como sus creaciones y destrucciones) de los objetos del usuario. Por tanto las aplicaciones que utilicen el framework de Spring (no Spring propiamente dicho) utilizarán Inversión de Control.

Creo que tras esta definición toca un ejemplito que sirva para aclarar algunas dudas (que seguramente no son pocas):

Sean dos clases cada una con su interfaz independiente: classA, classB, interfaceA e interfaceB. En classB tenemos un campo del tipo classA. Desde la clase principal, mainClass, se accede al campo del tipo classA de la clase classB.

Utilizando el método de programación habitual tendríamos lo siguiente:

public class ClassA {public String do(){return "Hello World";}}
 
public class ClassB {
   public ClassA a;
   public ClassB(){
      this.a = new ClassA();
   }
}

La clase principal seria:

public class main{
   public static void main(String args[]){
      ClassB b = new ClassB();
      System.out.println(b.a.do());
   }
}

En la salida estándar obtenemos:

$ Hello World

Analicemos el código del ejemplo. ¿Qué pasaría si las clases ClassA y ClassB pertenecieran a dos componentes totalmente distintos (p.ej. un conector JDBC y un cliente de servicios web)? ¿No estaríamos acoplando ambos componentes y haciendo que fueran totalmente dependientes uno del otro? ¿Que pasaría si decidiéramos cambiar un componente por otro distinto que en esencia tuviera la misma funcionalidad? ¿Tendríamos que cambiar ambos componentes? ¿Genera esto un código testeable unitariamente? Es decir, ¿podemos testear la clase ClassB sin testear la ClassA?

La respuesta a todas estas preguntas nos las puede dar el siguiente ejemplo:

public interface InterfaceA{String do();}
 
public interface InterfaceB{ InterfaceA getA();}
 
public class ClassA implements InterfaceA{public String do(){return "Hello World";}}
 
public class ClassB implements InterfaceB{
   private InterfaceA a;
 
   public void setA(InterfaceA a){this.a = a;}
   public InterfaceA getA(return this.a;)
}

La clase principal seria:

public class main{
   public static void main(String args[]){
      ClassB b = new ClassB();
      ClassA a = new ClassA();
      b.a = a;
      System.out.println(b.a.do());
   }
}

En este ejemplo no se están acoplando las clases ClassA y ClassB, con lo que conseguimos resolver todas las preguntas del ejemplo anterior. Hemos evitado el acoplamiento, ¿pero es cómodo? Si ahora necesito instanciar todas las clases y establecer sus campos, estoy mejorando la calidad de mi software, pero a un coste alto. Aquí es donde entra Spring:

public interface InterfaceA{String do();}
 
public interface InterfaceB{ InterfaceA getA();}
 
public class ClassA implements InterfaceA{public String do(){return "Hello World";}}
 
public class ClassB implements InterfaceB{
   private InterfaceA a;
   public void setA(InterfaceA a){this.a = a;}
   public InterfaceA getA(return this.a;)
}

Archivo de definición de beans (applicationContext.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.5.xsd">
<beans>
   <bean id="classA" />
   <bean id="classB">
      <property name="a" ref="classA"/>
   </bean>
</beans>

La clase principal seria:

public class main{
   public static void main(String args[]){
      ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
				new String[] { "applicationContext.xml" });
      InterfaceB b = ctx.getBean("classB");
      System.out.println(b.getA().do());
   }
}

La implementación anterior sería la más correcta posible: desde el método main se carga el contexto de Spring, que se encarga de instanciar todas las clases y de realizar la inyección de dependencias. Tras esta inicialización, obtenemos el "bean" desde el contexto a través del nombre, con lo que hemos diseñado una aplicación totalmente desacoplada y de una manera muy sencilla.

Sirva esto de rápida introducción a Spring. Y si no se han aclarado, utilicen los comentarios o sean pacientes; en poco tiempo le cogerán el gusto a este framework.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • BarraPunto
  • LinkedIn
  • Meneame
  • Netvibes
  • TwitThis

¿Te gustó este artículo?

¡Considera suscribirte a nuestro feed!

Comentarios (7) Trackbars (0)
  1. Muy buena iniciativa, me encanta el ejemplo de uso que acabas de poner. Mis conocimientos de Spring se reducen a a hacer lo que tú has hecho, pero muchas veces. Buena suerte con el blog!

  2. Nestoooooor que grande es este blog!!!!!

  3. Gracias marquitos.

    A ver si a lo largo de esta semana posteo otro artículo del uso del core de spring ;)

  4. Marquitos, estamos todos esperando tu blog contandonos tus aventuras con el reporting services y con los controles winforms! :D

  5. Jjajaja algún día montare una comunidad! xD

  6. Joder estas hecho un experto, esto mas que entradas de blog, son guias de inicio en toda regla.

    Suerte.

  7. Ahí está el objetivo ;)

    Gracias Onakzal!


Deja un comentario


Trackbacks are disabled.