AOP con AspectJ y Maven

1
16852

AOP con AspectJ y Maven

Índice de contenido

Introducción.

La programación orientada a aspectos es algo que cada vez está más presente en varios proyectos, y que gracias a Spring AOP se integra perfectamente en el framework de Spring como podemos ver en el tutorial Spring AOP: Cacheando aplicaciones usando anotaciones y aspectos con Aspectj de nuestro compañero Carlos. Pero no en todos los proyectos contamos con Spring, pero no por esto tenemos que descartar la programación de aspectos si es que nos hacen falta.

En este tutorial vamos a ver un ejemplo de programación de aspectos con AspectJ y como podemos integrarla dentro de nuestros proyectos de Maven mediante un plugin de compilación, sin necesidad de integrarlo con el framework de Spring.

Entorno

El tutorial está escrito usando el siguiente entorno:

AOP (Aspect Oriented Programming).

En este punto vamos a presentar los conceptos básicos de AOP que sirvan de base para alguién nuevo o de refresco para aquellos que lo conocen.

De forma general podemos decir que la programación orientada a aspectos trata de identificar y ocuparse de aquellos comportamientos que afectan de forma transversal a nuestra lógica de negocio. Tipicamente son del tipo:

  • Comprobaciones de seguridad (verificación de credenciales).
  • Gestión de transacciones (apetura y cierre)
  • Volcado de trazas.
  • etc.

Con AOP podemos implementar este tipo de comportamientos sin necesidad de modificar el código propio de la lógica de negocio.

Para terminar de asentar las bases de AOP vamos a ver un poco de su terminología principal:

  • Aspect: Es el comportamiento transversal que se aplica sobre aquella funcionalidad configurada bajo el aspecto. (verificación de credenciales, transacciones, trazas, etc.)
  • Join point: Es cualquier punto de la aplicación sobre el que se puede aplicar el aspecto. (Llamadas a métodos, acceso a atributos, etc.)
  • Advice: Es la acción que realiza un aspecto en un determinado join point. (volcado de trazas, etc.)
  • Pointcut: Es un conjunto de join points al que aplicar un advice. (ej. Todos lo métodos «setXXX» de una clase)

Integración de AspectJ con Maven.

Como hemos avanzado en la introducción, al no tener Spring debemos encontrar un modo de que nuestros aspectos se «enganchen» correctamente a nuestra aplicación, y se ejecuten en los casos necesarios.

AspectJ consigue realizar esto al compilar nuestro proyecto con un compilador propio. Podemos decir que al compilar una clase afectada por algún aspecto, el compilador de AspectJ modifica el código introduciendo las llamadas al aspecto.

Al tener nuestro proyecto gestionado con Maven, es necesario un plugin de Maven que en el momento de compilar realice estas modificaciones. El plugin en concreto es AspectJ compiler Maven Plugin. También deberemos tener incluidas las dependencias propias de AspectJ, por lo que en nuestro fichero «pom.xml» deberemo incluir el siguiente código:

 

De la configuración de este plugin, lo más destacable es que debe ejecutarse en el momento de compilacion tal y como podemos ver en sus «goals» específicos. Pero otro dato importante es su configuración con el elemnento «<source>» con valor «1.5»; que nos sirve para indicar que el nivel de compilación se corresponde con Java 1.5, de esta forma podemos utilizar anotaciones para nuestros aspectos, algo que nos simplifica bastante la configuración de los mismos.

Ejemplo.

Para ver rápidamente como podemos crear aspectos, vamos a implementar un sistema de trazas con aspectos. Tenemos el típico CRUD (Create, Read, Update, Delete) de contactos, donde deseamos que cada vez que se inserte, modifique o borre un contacto se deje una traza con el tipo de acceso.

Primero nos creamos nuestras clases de trazas.

 

 

 

 

Ahora debemos crearnos el DAO de acceso a datos. (Con ver el interfaz el suficiente para nuestro ejemplo, ahora veréis)

 

 

El punto interesante, se encuentra en que los métodos «delete», «insert» y «update» se encuentran anotado bajo la anotación «@TraceAnnotation». Esta anotación es la que nos sirve para indicar que éstos métodos serán «join points» de nuestro aspecto.

La anotación la hemos creado para marcar los métodos bajo el aspecto que vamos a crear, por lo que hemos creado una anotación específica para métodos y su código es el siguiente:

 

Finalmente nos queda por crear nuestro aspecto, que será el responsable de registrar los distintos tipos de trazas. Su código es:

 

Aquí lo más importante es ver como la clase está anotada bajo la anotación «@Aspect», que es una anotación propia de AspectJ, y que sirve para indicarle al compilador de AspectJ que esta clase es un aspecto.

Otro punto a destacar es el método «addTrace», que es el advice del aspecto (comportamiento a ejecutar). Se puede observar cómo este método está anotado con la anotación «@After» que indica que debe ejecutarse después de la llamada a los métodos anotados con «@TraceAnnotation».

Otras posibles opciones sería «@Before», para indicar que se ejecute antes de la llamada al método y «@Around» para indicar que debe ejecutarse tanto antes de la llamada al método como después.

Si observamos el código podemos ver como lo primero que hacemos es comprobar que la entidad sobre la que se está realizando la operación (insert, update o delete) no es de tipo «Trace» ya que ésta no interesan. Después recuperamos el tipo de operación, creamos la traza correspondiente y la guardamos en la base de datos.

Probando el ejemplo

Para poder probar nuestro aspecto nos creamos un test unitario que inserte, modifique y borre un contacto y depués de cada acción comprobaremos que se ha insertado la traza. El código del test es:

 

Conclusiones

Finalmente podemos ver cómo con AOP podemos implementar aquella funcionalidad que es transversal al resto de la aplicación, sin neecsidad de tener que cambiar el código propio de la lógica de negocio. También se puede observar como se consigue una mayor independencia de este tipo de tareas respecto al resto de la aplicación, el famoso bajo acoplamiento de las aplicaciones. Por ejemplo, si sobre el caso mostrado se quisiera cambiar el sistema de trazas a otro distinto, sólo habría que cambiar la implementación del aspecto, dejando el resto del código de nuestra aplicación sin tocar.

Si queréis, aquí podéis conseguir todo el código fuente de este ejemplo AOP con AspectJ y Maven.

Un saludo.
Borja Lázaro de Rafael.

1 Comentario

  1. Muy buen tutorial. Lástima que no me funcione 🙁 . He importado el proyecto Maven, he incluido en el pom.xml la dependencia a «commons-collections» que hacía falta, y he lanzado los test desde maven. Me da error este assert:

    Assert.assertEquals(1, dao.loadAll(Trace.class).size());

    …porque no entra en el aspecto, por lo que el número de trazas es 0 en vez de 1, que es lo que espera el test tras invocar al insert.

    ¿Sabes a qué se puede deber que no se evalue el aspecto? ¿Hay que lanzar los test de algún modo especial para que funcione el «weave»?

    Muchas gracias y un saludo 😉

Dejar respuesta

Please enter your comment!
Please enter your name here