domingo, 20 de julio de 2008

Introducción a Spring Framework

Spring es un framework open source creado por Rod Johnson, el cual fue inicialmente descrito en su libro “Expert One-on-One: J2EE Design and Development”. El objetivo de Rod Johnson era implementar un framework que permitiese desarrollar aplicaciones empresariales de manera más fácil y rápida, utilizando POJOs (Plain Old Java Object) para lograr cosas que antes eran solamente posibles con EJBs.

Uno de los principales objetivos de Spring es no ser intrusito. Esto quiere decir, que aquellas aplicaciones configuradas para utilizar “Beans” mediante Spring no necesitan depender de interfaces o clases de Spring, obteniendo su configuración a través de las propiedades de sus "Beans".

Este concepto puede ser aplicado a cualquier entorno, desde una aplicación J2EE hasta un applet.

Spring está compuesto por un conjunto características, las cuales están agrupadas en seis módulos principales:



El paquete “Core” es la parte más fundamental del framework ya que provee a este, las características de Inversión de Control (IoC) y Inyección de dependencias (ID). El concepto básico dentro del “Core” es el “BeanFactory”, el cual provee una sofisticada implementación del “Patrón Factory”, que remueve la necesidad generalizada de “Singletons” y nos permite desacoplar la configuración y especificación de las dependencias de nuestra lógica de programación.

El paquete “Context” está construido sobre una solida base provista por el paquete “Core”, el cual proporciona un medio de acceso a los objetos contenidos en el framework de forma tal, que recuerda en cierta medida a la manera en cómo trabaja el registro JNDI. Este paquete hereda algunas características del paquete “Beans” y añade soporte para internacionalización (I18N), propagación de eventos, carga de recursos y la transparente creación de contextos, como por ejemplo, un “Servlet Container”.

El paquete “DAO” provee una capa de abstracción a JDBC, eliminando la tediosa codificación propia de JDBC y el parseo de los códigos de errores específicos de cada proveedor de base de datos. Así también, este paquete proporciona mecanismos de manejo de transacciones tanto programáticamente como declarativamente, cuyo manejo no está restringido a clases que implementen algún tipo de interfaz especial, sino que también está pensado para cualquiera de nuestros POJOs.

El paquete “ORM” provee una capa de integración con las APIs más populares de “Mapeo Objeto-Relacional”, tales como JPA, JDO, Hibernate y iBatis. Usando este paquete nosotros pidremos utilizara cualquiera de estos ORM en combinación con todas las otras características que Spring ofrece.

El paquete “AOP” de Spring, provee una implementación para la programación “Orientada a Aspectos” compatible con el “AOP Alliance” que nos permite definir, por ejemplo, interceptores a un método (method-interceptors) y puntos de corte (pointcuts) para desacoplar limpiamente algunas funcionalidades implementadas en el código que lógicamente deberían conversar por separado.

El paquete “Web” de Spring provee características de integración orientadas a la Web, tales como funcionalidades para la carga de archivos, la inicialización del contenedor IoC usando “Servlet Listeners” y un contexto de aplicación orientado a la web.

El paquete “MVC” de Spring, provee una implementación del patrón MVC (Moldeo-Vista-Controlador) para las aplicaciones web. Spring MVC provee una limpia separación entre el código del modelo de dominio y los formularios web, integrándose a todas las otras características que este framework entrega.

Ejemplo Basico

Para poder comenzar a desarrollar en Spring lo primero que necesitamos es descargarnos la versión 2.5.5 desde www.springframework.org.

En la sección de “download” encontraran tres tipo de archivos a descargar: Spring 2.5.5 (spring-framework-2.5.5.zip), Spring 2.5.5 incluyendo la documentación (spring-framework-2.5.5-with-docs.zip) y Spring 2.5.5 incluyendo todas las dependencias (spring-framework-2.5.5-with-dependencies.zip). Para este ejemplo y los futuros ejemplos, necesitaremos la última de estas tres opciones.

Una vez descargados los archivos, procedemos a crear el proyecto. Para este caso, tenemos varias opciones: podemos utilizar Netbeans 6.x el cual ya incluye soporte para Spring, Eclipse 3.x al cual se le debe instalar Spring IDE o IntelliJ el cual también incluye soporte para Spring.

En este caso utilizare IntelliJ para los ejemplos.

Primero creamos el proyecto seleccionado la opción “File --> New Project…”. Luego seleccionamos la opción “Create Project from scratch” y presionamos el botón “Next”.



A continuación, ingresamos el nombre del proyecto, que para nuestro caso será “SpringBasico” y presionamos el botón “Next”.



Luego, seleccionamos la opción “Create source Directory” y presionamos el botón “Next”.

Por último, seleccionamos que la tecnología deseada para utilizar en el proyecto es “Spring” y presionamos el botón “Finish”. Con lo que se nos construirá la estructura básica de nuestro proyecto.



El único problema, es que la última versión de IntelliJ IDEA solamente tiene soporte hasta la versión 2.0.7 de Spring, razón por la cual necesitaremos cambiar la librería “Spring.jar” por la versión que nosotros descargamos.

Para esto, nos posicionamos sobre el proyecto, presionamos el botón derecho del mouse y seleccionamos la opción “Module Settings”.



Luego, en las opciones de “Project Settings” seleccionamos “Libraries”. Es aquí donde cambiaremos el nombre de nuestro paquete de librerías y modificaremos el “Spring.jar”.

El primer paso será cambiar el nombre del paquete “Spring-2.0.7” por “Spring-2.5.5”. Luego, seleccionamos la ruta del archivo “Spring.jar” y presionamos el botón “Detach”. Por último, presionamos el botón “Attach Classes…”, seleccionamos el archivo “Spring.jar” que se encuentra en la carpeta “dist” de la versión que descargamos anteriormente y presionamos el botón “Ok”.

Para finalizar, presionamos el botón “Apply” para que confirme y actualice todos los cambios, y presionamos el botón “OK”.

El último cambio lo deberemos realizar sobre el archivo “spring-config.xml”. Como IntelliJ solamente tiene soporta para Spring 2.0.7, la definición XSD de este archivo es para la versión 2 de Spring. Por esta razón, deberemos cambiar esta por la versión 2.5.



Para nuestro primer ejemplo, desarrollaremos una idea simple que nos permita ver algunos de los beneficios básicos de Spring.

Imaginemos que necesitamos construir un robot, al cual le ensamblaremos un par de piernas, un par de brazos y una cabeza. Una primera propuesta a nuestro problema sería la siguiente:











El problema con esta implementación es que el código esta “Altamente Acoplado”. Que sucedería si decidimos cambiar la implementación de un brazo? No solamente tendríamos que modificar la clase “BrazoImpl”, sino también la clase “RobotImpl”. Es aquí donde la inversión de control “IoC” y la inyección de dependencias “ID” nos ayudan (más información de IoC y ID la pueden encontrar aquí).

El primer cambio que tendremos que realizar al código, es que cada pieza del robot deberá implementar una interfaz, con lo cual estaremos definiendo un contrato para cada una de estas piezas, y en el caso de que necesitemos diseñar un nuevo brazo o una nueva pierna, simplemente deberemos implementar la interfaz asociada al tipo de pieza.

















Pero quien se encargara de ensamblar el robot? Aquí es donde Spring entra en acción. En el archivo “spring-config.xml” definiremos cada una de estas piezas como “Beans” de Spring.



Como podemos observar, para definir un bean en Spring se utiliza el tag “bean”, al cual se le asigna un “id” único y la clase que define al bean.

Utilizando el tag “property” se puede inyectar un valor al bean. El atributo “name” es el nombre del atributo de la clase que tiene definido un método set en el bean, y el atributo “value”, es el valor que se le inyectara a este bean a través del método set.

Ahora, nuestra clase Test es mucho más simple:



Hasta aquí todo bien, pero.....……que sucedería si tuviéramos que definir 60 beans que representen a algunos objetos del dominio de nuestra aplicación, los que a su vez dependen de 15 objetos de servicios o cualquier otra cosa. Lo único que conseguiríamos sería un gran archivo XML con muchas definiciones de beans.

Una solución sería dividir este XML, en XMLs más pequeños, pero igual seguiríamos con el problema de que en la medida que se necesiten nuevos bean se seguirán definiendo nuevos archivos XML.

Con la versión de Spring 2.5 tenemos una mejor opción, el uso de anotaciones!!. En esta versión, Spring provee un conjunto de anotaciones que resuelven la dependencia de los objetos sin tener que utilizar XML.

Veamos un ejemplo de esto:

















La anotación "@ Autowired" le informa a Spring, que deberá inyectar automáticamente la dependencia, basado en el tipo definido como Autowired (para nuestro caso, las piezas del robot).

Spring también nos permite definir que objeto será inyectado basándose no solamente en su tipo, sino también utilizando el nombre del bean, a través de la anotación "@ Qualifier".

Pero como le definimos un nombre a los beans? Utilizando la anotación "@Component". Con esta anotación, registramos un nuevo bean que se encuentra disponible para ser inyectado por el contenedor de Spring.

Con estas anotaciones, ya no es necesario definir los "Beans" en un XML.

Ahora, solamente nos queda decirle a Spring, que los bean se encuentran definidos utilizando anotaciones, para lo cual nuestro XML de configuración se reduce a esto:



Para nuestro test utilizaremos JUnit integrado a Spring:



Con este simple ejemplo ya podemos ver algunos de los conceptos básicos de Spring.

En el próximo post veremos las diversas opciones de configuración de los Beans utilizando XML y algunos conceptos básicos del “Core” como el "BeanFactory".

Si alguien quiere mas información sobre el paquete “JDBC”, José Miguel Selman está desarrollando una excelente serie de artículos introductorios que pueden encontrar aquí.

4 comentarios:

Anónimo dijo...

Excelente POST... Parece que los intentos de conquistar al mundo nos llevan hacia un modelo de desarrollo liviano, ágil y basado en componentes livianos :-)

Unknown dijo...

esta perfecto para comenzar a aprender Spring.

Anónimo dijo...

Mis primeros pasos con Spring...
Gracias

Ladymerch4 dijo...

Muy buen aporte, enhorabuena, se ve un código bien organizado y claridad de ideas.