jueves, 2 de septiembre de 2010

Spring 3 - Parte 1: Introducción

En la actualidad el desarrollo de aplicaciones empresariales, aunque es más sencillo ya que hay muchas herramientas, APIs, y Frameworks; los cuales aunque son opcionales, el aprender a usarlos nos ayudará a desarrollar nuestras aplicaciones en menos tiempo y a que estas sean más robustas y contengan menos errores.

También se vuelve un poco más complicado porque nuestras aplicaciones deben ser capaces de conectarse con otras aplicaciones y servicios. Además, como desarrolladores, somos los responsables de coordinar cada una de las partes de nuestra aplicación para que todo funcione correctamente.

Por si no fuera suficiente, debemos tomar en cuenta que debemos darle mantenimiento a nuestras aplicaciones, y que en algunos casos será necesario que cambiemos módulos o capas enteras de la misma para mejorarla; como por ejemplo sustituir nuestras consultas JDBC con Hibernate en los casos en los que sea prudente.

Afortunadamente existen super-frameworks que nos ayudan haciéndose cargo de todas o casi todas las “complicaciones” mencionadas anteriormente. Spring es el más popular de estos super-frameworks Java. Nos proporciona varios módulos los cuales abarcan la mayor parte de las cosas que debemos hacer en cualquiera de las capas de nuestras aplicaciones, desde plantillas para trabajar con JDBC o invocación de Web Services y JMS, pasando por sus propias soluciones, ORM o MVC (web), hasta integración con otros frameworks, como Struts 2, Hibernate, JSF, etc. Todo esto de una forma elegante y haciendo uso de muchos buenos principios de programación. Además Spring maneja la infraestructura de la aplicación, por lo que nosotros solo deberemos preocuparnos de la lógica de la misma (y de la configuración de Spring).

En esta serie de tutoriales aprenderemos como usar Spring, en su versión 3, para facilitarnos la vida en el desarrollo de nuestras aplicaciones Java. Para aprender a usar Spring de forma correcta hay que ver muuucha teoría, así que en este primer tutorial hablaremos solo de los conceptos básicos de Spring y explicaré cada una de las partes, junto con su teoría correspondiente, en el post correspondiente.

Spring es, como lo definen sus autores, un framework ligero para construir aplicaciones empresariales. Aunque Spring se encuentra dividido en distintos módulos, cada uno de los cuales se encarga de partes diferentes de nuestra aplicación, no deja de ser un monstruo, ya que es tan grande que alguien podría nunca usar todos estos módulos en aplicaciones pequeñas o medianas; pero en aplicaciones grandes o realmente grandes puede ahorrarnos mucho trabajo ya que puede coordinar todas las partes de la aplicación. Esta separación en módulos nos permite usar solo las partes que necesitamos, sin tener la carga de los que no usemos.

Spring está diseñado para no ser intrusivo, esto significa que no es necesario que nuestra aplicación extienda o implemente alguna clase o interface de Spring (si no lo queremos), por lo que nuestro código de lógica quedará libre y completamente reutilizable para un proyecto sin Spring, o por si debemos quitarlo de una aplicación que ya lo esté usando. Gracias a esto es posible usar un POJO o un objeto Java para hacer cosas que antes solo podían hacerse con EJBs. Sin embargo la utilidad de Spring no es solo para el desarrollo de aplicaciones web, o no solo en el servidor. Cualquier aplicación Java puede beneficiarse del uso de Spring.

Además, si usamos Spring de la forma correcta (lo cual no es difícil) nuestra aplicación quedará dividida en capas bien delimitadas, y con buenas prácticas de programación.

El núcleo de Spring está basado en un principio o patrón de diseño llamado Inversión de Control (IoC por sus siglas en inglés). Las aplicaciones que usan el principio de IoC se basan en su configuración (que en este caso puede ser en archivos XML o con anotaciones como en Hibernate) para describir las dependencias entre sus componentes, esto es, los otros objetos con los que interactúa. En este caso “inversión” significa que la aplicación no controla su estructura; permite que sea el framework de IoC (en este caso Spring) quien lo haga.

Por ejemplo, supongamos que tenemos una clase “AlmacenUsuario”, que depende de una instancia de una clase “UsuariosDAO” para realizar su tarea. “AlmacenUsuario” crea una instancia de “UsuariosDAO” usando el operador “new” u obtiene una de algún tipo de Fabrica. Usando la técnica de IoC, una instancia de “UsuariosDAO”, o una subclase de esta, es proporcionada a “AlmacenUsuario” en tiempo de ejecución por el motor de Spring. En este caso “UsuariosDAO” también podría ser una interface y Spring se encargará de proporcionarnos una instancia de una clase que implemente esa interface. Esta inyección de dependencia en tiempo de ejecución ha hecho que a este tipo de IoC se le dé el nombre más descriptivo de inyección de dependencia (DI por sus siglas en inglés). El concepto importante es que los componentes no saben cuál implementación concreta de otros componentes están usando; solo ven sus interfaces.

El uso de interfaces y DI son mutuamente benéficos, ya que hace más flexible y robusta nuestra aplicación y es mucho más fácil realizar pruebas unitarias. Pero la complejidad de escribir código que maneje las dependencias entre los componentes de una aplicación diseñada para usar interfaces puede llegar a ser mucho y esto, además, hace que los desarrolladores tengamos que escribir aún más código.

Afortunadamente, usando DI reducimos la cantidad de código extra que debemos escribir, para un diseño basado en interfaces, casi a cero.

En el contexto de DI, Spring actúa como un contenedor que proporciona las instancias de las clases de nuestra aplicación todas las dependencias que necesita, pero en una forma no intrusiva y automática. Todo lo que debemos hacer es crear un archivo de configuración que describa las dependencias; Spring se hará cargo del resto.

Como dije antes: Spring es un contenedor ya que no solo crea los componentes de nuestra aplicación, sino porque contiene y maneja al ciclo de vida y configuración de estos componentes. En Spring, podemos declarar cómo debe ser creado cada uno de los objetos de nuestra aplicación, cómo deben ser configurados, y cómo deben asociarse con los demás.

La implementación de DI de Spring se enfoca en el acoplamiento débil: los componentes de nuestra aplicación deben asumir lo menos posible acerca de otros componentes. La forma más fácil de lograr este bajo acoplamiento en Java es mediante el uso de Interfaces. Como cada componente de la aplicación solo está consciente de la interface de otros componentes, podemos cambiar la implementación del componente sin afectar a los componentes que usan el nuevo componente. Hablaré un poco más de esto cuando veamos los ejemplos.

El uso de DI tiene como beneficios, además de lo que ya he mencionado arriba, los siguientes:

  • Reduce el código pegamento: Esto quiere decir que reduce dramáticamente la cantidad de código que debemos escribir para unir los distintos componentes. Aunque algunas veces esté código puede ser tan simple como usar el operador “new” para instanciar un nuevo objeto, otras puede ser más complejo, como realizar una búsqueda de dicha dependencia en un repositorio a través de JNDI, como en el caso de los recursos remotos. En esto caso, el uso de DI puede reducir de forma dramática la cantidad de código pegamento (o glue code) proporcionando búsquedas automáticas.
  • Externaliza dependencias: Como es posible colocar la configuración de dependencias en archivos XML podemos realizar una reconfiguración fácilmente, sin necesidad de recompilar nuestro código. Gracias a esto es posible realizar el cambio de la implementación de una dependencia a otra (como en el ejemplo de Hibernate que mencioné antes)
  • Las dependencias se manejan en un solo lugar: Toda la información de dependencias es responsabilidad de un solo componente, el contenedor de IoC de Spring, haciendo que este manejo de dependencias más simple y menos propenso a errores.
  • Hace que las pruebas sean más fáciles: Nuevamente, como nuestras clases serán diseñadas para que sea fácil el reemplazo de dependencias, podemos proporcionar mocks o dummies, que regresen datos de prueba, de servicios o cualquier dependencia que necesite el componente que estamos probando.

Como podemos ver, el uso de DI nos proporciona muchos beneficios, pero no sin sus correspondientes desventajas. En particular, es difícil ver qué implementación particular de una dependencia está siendo usada para qué objeto, especialmente para alguien que no está familiarizado con esta forma de trabajo.

¿Y por qué tanto hablar de DI? Pues porque estos dos conceptos (IoC y DI) son los puntos centrales alrededor del cual gira todo en Spring, así que es mejor entenderlos desde el principio ^_^.

Como dije: Spring está dividido en alrededor de 20 módulos y colocados en los siguientes grupos:

  • Contenedor Central (Core Container)
  • Acceso a Datos / Integración
  • WEB
  • AOP (Programación Orientada a Aspectos)
  • Instrumentación
  • Pruebas

Estos grupos se muestran en la siguiente imagen:



A lo largo de estos tutoriales trataré de explicar la mayor cantidad de módulos. Pero como dije antes: Spring es en realidad un monstruo. Así que probablemente cuando termine de explicarlos todos, ya habrá salido una nueva versión, así que me centraré solo en los más importantes y en su integración con otros frameworks que comencemos a usar en otros tutoriales.

En general, estas son algunas de las características de Spring:

  • Simplificación de la programación orientada a aspectos.
  • Simplificación del acceso a datos.
  • Simplificación e integración con JEE
  • Soporte para planificación de trabajos.
  • Soporte para envió de mail.
  • Interacción con lenguajes dinámicos (como BeanShell, JRuby, y Groovy).
  • Soporte para acceso a componentes remotos.
  • Manejo de Transacciones.
  • Su propio framework MVC.
  • Su propio Web Flow.
  • Manejo simplificado de excepciones.

La versión 3 de Spring es una versión revisada y mejorada de la versión estable anterior (2.5), que incluye nuevas características, entre las que se incluyen:

  • Soporte para Java 5: Proporciona configuración basada en anotaciones y soporta características como varargs y generics, además la parte web es compatible con las versiones 1.4 y 5 de Java EE. Debido a esta nueva característica, ahora es necesario tener el JRE versión 5 o superior.
  • Lenguaje de Expresiones (SpEL): En esta nueva versión se incluye un lenguaje de expresiones que puede ser usando cuando se definen beans, tanto en XML como con anotaciones y también da soporte a través de todos los módulos de Spring.
  • Soporte para Servicios Web REST: Ahora Spring soporte servicios web de tipo REST.
  • Soporte para Java EE6: Ofrece soporte de características como JPA 2.0, JSF 2.0 y JRS 303 (validaciones de Beans).
  • Soporte para bases de datos embebidas: Un soporte conveniente para bases de datos embebidas como HSQL, H2 y Derby.
  • Soporte para formateo de datos mediante anotaciones: Ahora los campos de fecha, divisas, etc., serán formateados automáticamente y convertidos usando anotaciones.
  • Nueva organización de los módulos: Los módulos han sido revisados y separados en diferentes paquetes, mas organizados, de acuerdo a su funcionalidad. Para que se den una idea, estos son los nuevos paquetes:
    • org.springframework.aop
    • org.springframework.beans
    • org.springframework.context
    • org.springframework.context.support
    • org.springframework.expression
    • org.springframework.instrument
    • org.springframework.jdbc
    • org.springframework.jms
    • org.springframework.orm
    • org.springframework.oxm
    • org.springframework.test
    • org.springframework.transaction
    • org.springframework.web
    • org.springframework.web.portlet
    • org.springframework.web.servlet
    • org.springframework.web.struts

A lo largo de estos tutoriales veremos algunos de estos paquetes. Aunque este post, como ya se habrán dado cuenta es solo de teoría, crearemos la librería para NetBeans de Spring que estaremos usando en esta serie de tutoriales.

Así que lo primero que haremos es abrir el NetBeans. En realidad el NetBeans 9 ya tiene una biblioteca de Spring 3, la 3.0.2.



Pero han salido actualizaciones desde esta versión (actualmente la versión más nueva es la 3.0.4). Así que lo que haremos es crear una nueva biblioteca que hará uso de los jars que necesitamos (y los cuales iremos incrementando en cada tutorial).

Bajamos la última versión de Spring de su página de descargas. También necesitaremos el archivo “commons-logging-api-1.1.1.jar” que podemos encontrar en la página de descarga de commons-logging, en el archivo "commons-logging-1.1.1-bin.zip”, tal y como lo hicimos en los tutoriales de JasperReports.

Una vez que hayamos bajado el archivo de Spring, lo descomprimimos y veremos que tiene un subdirectorio “dist” el cual contiene todos los jars de Spring para cada uno de sus módulos. Vamos al NetBeans y nos dirigimos al menú “Tools -> Libraries”.



En la ventana que se abre presionamos el botón “New Library...”:



En esta nueva ventana colocamos como nombre de la biblioteca "Spring3" y como tipo dejamos "Class Libraries":



Ahora que tenemos nuestra biblioteca , presionamos el botón “Add Jar/Folder” para agregar los nuevos archivos que conformarán la biblioteca:



Agregamos a la biblioteca los siguientes archivos:

  • org.springframework.asm-3.0.4.RELEASE.jar
  • org.springframework.beans-3.0.4.RELEASE.jar
  • org.springframework.context-3.0.4.RELEASE.jar
  • org.springframework.core-3.0.4.RELEASE.jar
  • org.springframework.expression-3.0.4.RELEASE.jar
  • commons-logging-api-1.1.1.jar (que bajamos aparte)

Con estos es suficiente para hacer nuestros hola mundo iniciales :D. Una vez seleccionados estos archivos, nuestra biblioteca debe verse así:



Presionamos el botón “OK” y nuestra biblioteca estará lista para ser usada… en los siguientes tutoriales ^_^.

Por el momento hemos cubierto una muy pequeña parte de la teoría con respecto a Spring 3, que iremos ampliando en los siguientes posts, así que no desesperen, pronto comenzaremos a usar este framework, que muchas alegrías (y dolores de cabeza) nos dará a más de uno.

No olviden dejar cualquier comentario, duda o sugerencia en la sección de comentarios.

Saludos.

Entradas Relacionadas:

41 comentarios:

  1. Muy claro el tutorial, quedo a la espera de los siguientes.

    Gracias y felicitaciones

    ResponderEliminar
  2. Lo mismo digo. Deseando empezar la segunda parte. Gran trabajo.

    ResponderEliminar
  3. Exelente material como ninguno que he visto ,,
    mil gracias por tu tiempo..

    gracias esperando el proximo material..

    ResponderEliminar
  4. Muy buen tutorial... gracias por su tiempo y estamos esperando el otro :-)

    ResponderEliminar
  5. felicitaciones esta bueno el tutorial, aqui estamos al pendiente de lo que sigue.

    ResponderEliminar
  6. Monty debo admitirlo eres bueno, buena explicación :D

    ResponderEliminar
  7. Mejor explicado no pudo haber sido, creo que este si es el verdadero camino para aprender Spring. Adelante, estaremos esperando los siguientes tutoriales

    ResponderEliminar
  8. Amigo y que pasó con los siguientes tutoriales sobre Spring? cuando publicas al menos otra parte? quiero empezar a usar este framework y nadie mejor que ud, que lo explica de manera excelente y paso a paso.

    ResponderEliminar
  9. Saludos a Todos.

    Muchas gracias a todos los que han preguntado por la siguiente parte del tutorial. Les pido por favor que no se desesperen, ya está en proceso, no crean que se me ha olvidado ^_^.

    Aún falta agregar algunos pequeños detalles, así como darle una revisión. Solo les pido no se desesperen. Si tienen alguna duda puntual, pueden anotarse en el grupo de facebook y comentar ^_^.

    Saludos

    ResponderEliminar
  10. Sigue adelante Alex, este sera un grandioso turorial como el de hibernate, estaremos esperandolo.

    ResponderEliminar
  11. Excelente tutorial gracias por tu tiempo.

    ResponderEliminar
  12. Muchísimas gracias, el tutorial está de lujo. Voy a seguir con la segunda parte. Saludos

    ResponderEliminar
  13. Hola Alex!!

    Cómo estas?? Oye una pregunta, cuando se utiliza Spring con Hibernate y tengo mis DAO's declarados en el applicationContext y para obtener una referencia al DAO getApplicacionContext().getBean("nombreDAO")

    en mis clases DAO's tengo que abrir y cerrar explisitamente la transaccion para cuando hago consultas o lo hace spring???

    Saludos XD XD

    ResponderEliminar
  14. @JUAN CARLOS
    Hola Juan Carlos;

    En ese caso depende cómo lo manejes. Puedes hacer que Spring maneje de manera automática las transacciones si indicas esto en el archivo de configuración (más sobre esto en los siguientes tutoriales XD)

    ResponderEliminar
  15. hola Alex

    pues veras, en todas mis clases DAO tengo la anotacion @Transactional por es mi duda si es realmente necesario iniciar la transaccion explicitamente o dejar a spring que haga eso

    ResponderEliminar
  16. Alex muy bueno este primer tutorial de spring!!!! siempre tan claro y conciso, voy por los proximos dos tutoriales gracias por este conocimiento que compratis.Saludos desde Argentina

    ResponderEliminar
  17. ola visiten mi blog en este caso hago uso de base de datos con spring :)

    http://edwincalle.blogspot.com/2011/09/uso-de-jdbc-con-pool-empresarial-en.html

    ResponderEliminar
  18. Me parece muy bueno este tutorial, se lo recomendaré a mis camaradas :)

    ResponderEliminar
  19. Hola muchas gracias por esta valiosa guia, totalmente cierto cuando dicen "En particular, es difícil ver qué implementación particular de una dependencia está siendo usada para qué objeto, especialmente para alguien que no está familiarizado con esta forma de trabajo."

    Ahora a aprender se ha dicho-

    Saludos

    ResponderEliminar
  20. Excelente trabajo. Gracias por dedicar tiempo esfuerzos para elaborar estos tutoriales.

    ResponderEliminar
  21. Gracias, aunque sea principiante, lo entedi a la perfeccion, bueno unos conceptos no pero esos los estudiare aparte jejeje Gracias

    ResponderEliminar
  22. Así da gusto adentrarse en un nuevo framework. Gracias :)

    A por el segundo capítulo!!!

    ResponderEliminar
  23. Muy buen post. Se te agradece, me aclara muchas dudas respecto a spring.

    ResponderEliminar
  24. Hola Alex, Muy buen tutorial, es lo mejor que he visto para comezar con el Framework de Spring, un saludo.

    ResponderEliminar
  25. Excelente. Netbeans 7.3 ya trae la libraría.

    ResponderEliminar
  26. buen tutorial.... espero el resto para terminar de usar spring....

    dentro de todo lo que escribiste, vi algo que me parecio un poco futurista o talvez exista y yo no lo conosco, pero cuando yo entro a la pagina de netbeans, encuentro que la version mas reciente es la 7.3 hasta la fecha de hoy 20 de junio de 2013... si tu tienes netbeans 9, serian tan amable de poner el link para descargarlo...


    Atento a tus comentarios

    ResponderEliminar
  27. Me hubiese gustado ver los ejemplos usando Eclipse o el IDE de Spring (Que tambien es Eclipse) para eso mi unica pregunta es... ¿Cual es mas usado para trabajar con Spring, NetBeans o Eclipse?

    ResponderEliminar
  28. Estoy de acuerdo con un comentario anterior, es el mejor tutorial para introducirse en Spring. ¡Felicidades!

    ResponderEliminar
  29. Excelente tutorial clarisimo con los ejemplos felicidades!

    ResponderEliminar
  30. Hermano muchas gracias por la información tan valisa,,,, gracias

    ResponderEliminar
  31. Excelente explicación... muchas gracias!!!

    ResponderEliminar
  32. Muchas gracias, verdaderamente ayuda mucho, con este tutorial, saludos desde México...

    ResponderEliminar
  33. Excelente trabajo, muchas gracias por compartir tus conocimientos.

    ResponderEliminar
  34. gracias amigo que excelente explicacion...

    ResponderEliminar
  35. Si les aparece el siguiente error al ejecutar las aplicaciones

    Error creating bean with name 'org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0': Cannot resolve reference to bean 'pointcutsPersistencia' while setting bean property 'pointcut'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'pointcutsPersistencia': Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException

    deben añadir las siguientes librerías:
    aspectjrt.jar
    aspectjweaver.jar

    tal como lo dicen en esta página
    http://forum.spring.io/forum/spring-projects/aop/116055-probleme-when-adding-aop-in-my-application-context

    ResponderEliminar
  36. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  37. La explicación está excelente, muy buen tutorial en español (es difícil encontrar buenos tutoriales en nuestro idioma). También podrías mejorar la última parte usando Maven en vez de las "libraries" de Netbeans. Saludos!

    ResponderEliminar