SlideShare uma empresa Scribd logo
1 de 34
Baixar para ler offline
Chapter 1. Aspect Oriented
Programming

              Table of Contents
              Motivaciones ................................................................................................................ 1
              Evolución de las metodologías de programación ................................................................ 3
              AOP en el mundo real ................................................................................................... 4
                    Hype Cycle .......................................................................................................... 4
                    ¿Dónde se utiliza AOP? ......................................................................................... 6
              Introducción a AOP ...................................................................................................... 7
                    Metodología AOP ................................................................................................. 7
                    Anatomía de un lenguaje orientado a aspectos ........................................................... 8
                    Beneficios de la metodología AOP ........................................................................... 9
                    Verdades y mentiras sobre AOP ............................................................................ 10
              Visión general de AspectJ ............................................................................................. 11
                    Introducción a AspectJ ......................................................................................... 11
                    Modelo de Joint Point ......................................................................................... 11
                    Crosscutting dinámico .......................................................................................... 18
                    Aspectos ............................................................................................................ 24
                    Resumen ............................................................................................................ 25
                    Ejemplos reales ................................................................................................... 26
              Bibliografía ................................................................................................................ 33


Motivaciones
              Antes de profundizar en la temática propia de la orientación a aspectos y sus aplicaciones en el mundo
              real, sería conveniente describir las motivaciones principales que han ocasionado la escritura de este
              capítulo de la memoria.

              La primera de ellas ha sido la intención de introducir al lector en algunas de las técnicas de desarrollo
              avanzadas utilizadas en la actualidad por los equipos de desarrollo de software más vanguardistas.
              La segunda está relacionada con el desarrollo de nuevas herramientas de programación y, por ende,
              con la herramienta desarrollada como ejemplo de este proyecto: R-Eclipse. Si el lector desconoce
              muchos de los términos definidos en esta sección no se preocupe, a lo largo del capítulo comprenderá
              la terminología aquí utilizada.

              En los últimos años han surgido muchos lenguajes similares a Java que se ejecutan sobre la propia
              máquina virtual de este último (JVM), lo cual es un indicador bastante fiable del futuro del desarrollo
              de aplicaciones sobre la plataforma Java.1Sin embargo, Eclipse y su solución JDT, no ofrecen soporte
              para la integración de estos nuevos lenguajes en su modelo Java subyacente. Por ejemplo, no existe
              un modo de incluir jerarquías de tipos,jerarquías de llamadas, etc.




1
 R Eclipse no ha utilizado el enfoque descrito en esta sección por dos motivos principalmente; el primero de ellos es que R no es un lenguaje
similar a Java ni corre bajo su máquina virtual. El segundo de ellos consiste en que el framework base de desarrollo, DLTK, no utiliza la
arquitectura descrita en estas líneas.




                                                                     1
Aspect Oriented Programming


Figure 1.1. Herramientas para nuevos lenguajes




Algunos de los problemas que se encuentran los ingenieros de software cuando intentan construir
herramientas para algunos de los lenguajes descritos anteriormente son:

• Necesidad de acoplarse al modelo ofrecido por JDT. No se puede.

• Necesidad de acoplarse al motor de indexación de código fuente. No se puede.

• Necesidad de acoplarse al parser de JDT. No se puede.

Una aproximación utilizada por muchos entornos de desarrollo de lenguajes actuales como pueden ser
Scala o Groovy es la utilización del servicio de tejido de JDT. Las características principales son:

• Utiliza AspectJ añadiendo puntos de unión al modelo JDT

• Se encapsula en puntos de extensión de Eclipse, haciéndolo extensible a terceras partes.

• Utiliza un proyecto de Eclipse conocido como Equinox Aspects que soporta el proceso de tejido en
  tiempo de carga en un entorno OSGI.

El siguiente gráfico ilustra como funciona el proceso anterior:




                                            2
Aspect Oriented Programming


    Figure 1.2. Proceso de acoplamiento al JDT




    A lo largo de las siguentes secciones se introducirá la terminología AOP así como la definición de
    sus elementos más relevantes.


Evolución de las metodologías de
programación
    La ingeniería del software ha recorrido un largo camino desde sus inicios: desde el código máquina
    hasta la orientación a objetos pasando por los lenguajes procedimentales. Analizando de manera
    somera la evolución de las metodologías de programación observamos cómo el modelo procedimental
    introdujo la abstracción funcional y la orientación a objetos los conceptos de composición,
    reutilización y encapsulación. Este último paradigma ha sido, posiblemente, una de las mayores
    contribuciones al mundo del software durante toda su historia y,en la actualidad, es el paradigma de
    programación utilizado en la mayor parte de los grandes desarrollos de software.

    Entre todas las ventajas del paradigma de orientación a objetos, en el párrafo anterior se destacaba,
    no al azar, la reutilización y la encapsulación pero . . . ¿siempre es posible ubicar en el mismo lugar
    todas las tareas relacionadas con una misma función?, ¿en alguna ocasión has visto un fragmento de
    código que no encaja en ninguna clase en particular?.

    Imaginemos un sistema en el que determinadas operaciones necesitan llevar a cabo una gestión
    de transacciones. Resultaría sumamente complicado,por no decir imposible, modularizar todos los
    conceptos necesarios en un sistema transaccional: inicialización, comunicación con el manager de
    transacciones, rollbacks, . . . Esto es debido a que todos los métodos de un objeto que requieren
    un control de transacciones necesitan ser conscientes que la operación a realizar se ejecuta bajo un
    control transaccional, para comportarse de manera acorde al funcionamiento requerido. Resumiendo,
    el código encargado de la gestión de transacciones estaría ubicado en cada uno de los objetos que
    lo necesite. La solución comunmente adoptada a este problema es copiar y pegar el código en todas
    aquellas partes en las que es necesario, resultando evidente, que dicha solución no permite disponer
    de una buena modularización y dificulta las labores de mantenimiento y evolución del código. Este




                                                3
Aspect Oriented Programming


     fenómeno es conocido como scattering , puesto que el código relacionado con un mismo asunto se
     encuentra repartido a lo largo de todo el sistema.

     Sumemos, además, que los módulos que contienen código relativo a muchos asuntos diferentes tienden
     a ser, en general, menos reutilizables. El fenómeno en el que diferentes asuntos son entremezclados
     en el código se conoce como tangling .

     La problemática introducida en los párrafos anteriores, tangling y scattering , afecta al diseño y
     desarrollo de software de muchas y diferentes maneras. Veamos alguna de las principales:

     • Trazabilidad reducida. La implementación de diferentes conceptos en un mismo lugar dificulta el
       proceso de establecimiento de una relación entre los requisitos y su implementación y viceversa.
       Así por ejemplo, para completar la trazabilidad del requerimiento de autenticación podríamos llegar
       a examinar todos los módulos del sistema.

     • Baja producitividad. Varios conceptos no relacionados que han sido implementados en un mismo
       lugar ocasiona que la atención se disperse a lo largo de todos ellos. La falta de un objetivo
       concreto provoca que los desarrolladores se vean obligados a manejar diferentes conceptos no
       relacionados con el objetivo principal. En muchas ocasiones,la construcción de un módulo implicará
       la participación de diversos desarrolladores, con diferentes perfiles, o que el desarrollador tenga
       conocimiento en todos los ámbitos que se están incluyendo en el nuevo módulo.

     • Escasa reutilización del código. Los conceptos implementados en un módulo podrían ser requeridos
       por otros módulos con funcionalidades similares

     • Baja calidad. El code tangling provoca que el código sea más difícil de leer, de ubicar los potenciales
       problemas y de hacer revisiones del mismo. Por ejemplo, la revisión de código de un módulo en
       el que se implementan diversos conceptos requerirá la presencia de expertos en cada uno de ellos.
       A menudo muchos de estos expertos no estarán disponibles de manera simultánea, y el resto no
       prestará demasiada atención en los temas que se encuentren fuera de su área de conocimiento.

     • Dificultad para llevar a cabo evoluciones. La falta de recursos o una visión incompleta derivan en un
       diseño que maneja únicamente los conceptos actuales. Cuando aparezcan nuevos requerimientos,a
       menudo, nos veremos obligados a reimplementar. Dado que la implementación no se encuentra
       modularizada,la inclusión de un nuevo requerimiento podría obligar a realizar cambios en todos
       los módulos.

     Los problemas descritos en los puntos anteriores han servido como impulso en la búsqueda de nuevos
     y mejores enfoques en la arquitectura, diseño e implementación. AOP ofrece una solución a todos los
     problemas anteriores.


AOP en el mundo real
     ¿Qué lugar ocupa la orientación a aspectos en el mundo real? ¿Deberíamos prestarle atención o
     ignorarlo por completo? ¿Cuáles son los beneficios aportados? ¿y los posibles riesgos de adopción de
     esta tecnología?. Estas y otras preguntas serán respondidas, desde un punto de vista práctico, en los
     siguientes subapartados de esta sección.


Hype Cycle
     Hype Cycle es una representación gráfica del grado de madurez, adopción y aplicación en el mundo
     real de una tecnología determinada. Es importante comprender bien el gráfico anterior, y la posición
     de la tecnología que se está considerando; en este caso, AOP, puesto que se dispondrá de una visión
     mucho más ajustada de los riesgos y beneficios a los que nos estamos exponiendo.




                                                  4
Aspect Oriented Programming


       Figure 1.3. Diagrama de componentes de R-Eclipse




       La interpretación de la curva Hype Cicle implica cinco fases diferentes las cuales analizaremos a
       continuación, relacionándolas, evidentemente con AOP.

Activación de la tecnología
       Este es el momento en el que la tecnología aparece con la intención/promesa de solucionar un conjunto
       determinado de problemas. Podría ser el anuncio de un nuevo producto o la liberación de una nueva
       versión de un producto ya existente.

       En el caso de AOP, este proceso de activación se produjo en 2002 con el lanzamiento de AspectJ 1.0,
       seguido de una liberación mucho más importante (AspectJ 1.1) en el año 2003. Mucha gente se dio
       cuenta del potencial de AspectJ, especialmente su utilización en aplicaciones empresariales.

Expectativas irreales ("peak")
       Durante esta fase la tecnlogía se hace muy popular. Todo el mundo quiere conocerla y tiene una
       opinión sobre ella aunque muy poca gente la utiliza en aplicaciones reales.

       Durante el año 2004 la mayoría de desarrolladores que trabajaban en Aspectj y AspectJ Development
       Tools (AJDT) eran integrantes de IBM. Esta inversión por parte de IBM proporcionó una base sólida
       a AspectJ.

       La ausencia de una adopción masiva hizo que el uso de la tecnología se conviertiese en una auténtica
       aventura. Afortunadamente para AspectJ el pico en esta fase no fue demasiado eleveado, sobre todo
       debido al manejo de las expectativas que realizaron sus principales evangelistas. Esta gestión provocó
       un pico más bajo en el hype cycle, lo que supuso una caída mucho menor en la siguiente fase.

Desilusión
       Esta es la fase de ciclo Hype en la que la tecnología comienza a perder toda la atención que se le había
       prestado hasta el momento.

       Mientras que los equipos que la adoptaron desde sus inicios continuan utilizándola con el objetivo
       de obtener una ventaja competitiva, muchos otros comienzan a observarla con cierto escepticismo.
       Nuevas tecnologías aparecen en escena aportando soluciones diferentes al mismo problema. Resulta




                                                    5
Aspect Oriented Programming


       interesante destacar que muchos de estos nuevos competidores están en la fase de "expectativas
       irreales".

       AOP atravesó esta fase durante 2006 aproximadamente. Enterprise Java Beans ofrecía una
       seria competencia, permitiendo implementar funcionalidades transversales como seguridad o
       transaccionalidad de una manera modular. Pero EJB no era el único competidor, y tampoco el más
       importante. La aparición de lenguajes dinámicos como Groovy o Ruby y sus frameworks asociados,
       Grails y Rails, supuso una dura competencia para AOP. El modelo de metaprogramación del que
       disponen estas tecnologías facilitaba una nueva solución para realizar la modularización de funciones
       transversales.

Viendo la luz
       Numerosos factores intervienen en el desarrollo de esta fase: maduración de la tecnología, cambios
       en la misma para acercarse a la realidad, búsqueda de un contexto de uso en el que realmente se cause
       impacto o la "desilusión" con otras alternativas, que en su momento fueron competidores, son algunas
       de ellas.

       En el caso de AOP, el comienzo de esta fase se produjo cuando algunos de los líderes del proyecto
       abandonaron IBM para fichar por SpringSource:Adrian Colyer,Andy Clement, Andrew Eisinberg, . . .,
       conviertiendo a AspectJ en un proyecto más del portfolio de Spring. Analicemos los factores
       enumerados anteriormente:

       • Acercamiento a la realidad:La introducción de anotaciones en Java 5, los cambios en la sintáxis
         o la supresión del proceso de weaving si se utiliza conjuntamente con Spring fueron algunos de
         los cambios realizados. La mejora en las herramientas de desarrollo fue otra de las respuestas a las
         necesidades reales de los usuarios.

       • Contexto de utilización: la influencia de Spring: En sus inicios AspectJ carecía de un contexto
         de utilización definido (C nació en el ámbito de los sistemas operativos, C++ en el contexto de
         interfaz de usuario, etc). Ha sido Spring la que le ha proporcionado a AspectJ un contexto de uso
         bien definido: la aplicaciones empresariales.

       • Desilusión con los competidores: Anteriormente indicamos que EJB permitía modularizar los
         conceptos transversales de un sistema. Los desarrolladores se dieron cuenta de que la solución
         ofrecida era demasiado pesada en la mayoría de las ocasiones. La versión 3 de EJB introdujo
         interceptores, un concepto similar a los advices de AspectJ, aunque carecían de un modelo de unión.

         Los lenguajes dinámicos ofrecen una gran alternativa a AspectJ aunque son relativamente nuevos.
         Tendremos que esperar el paso del tiempo y el uso en grandes aplicaciones empresariales para
         determinar la evolución de los mismos, y ver cómo continúa evolucionando AspectJ.

Plena productividad
       Es la última fase definida en el ciclo Hype. En esta situación la tecnología está ampliamente difundida
       y se utiliza en las solución de problemas para los que ofrece una gran respuesta. Será en esta fase
       cuando se produzca una aceptación mavisa de la tecnología.

       En la actualidad,Java o C , se encuentran en esta fase. AOP y AspectJ deberán alcanzar este nivel con
       el paso del tiempo.

¿Dónde se utiliza AOP?
       A continuación se analizarán algunos de los principales ámbitos de aplicación de AOP

Aplicaciones empresariales
       Gestión de transacciones, seguridad, auditoría, monitorización, gestión de la concurrencia, manejo
       de errores y un largo ecétera son funcionalidades transversales en la mayoría de aplicaciones
       empresariales.




                                                   6
Aspect Oriented Programming


               Aquellas aplicaciones que usen Spring como base de su arquitectura ya estarán utilizando algunos
               de los aspectos que vienen facilitados por el framework. Gracias a las anotaciones, concretamente
               @Aspect, la construcción de aspectos se ha convertido en una tarea habitual.

Web y servidores de aplicaciones
               Aplicación de políticas, FFDC, recolección de contextos,trazabilidad o monitorización son algunas de
               las funcionalidades basadas en AOP que podemos encontrar en los servidores de aplicaciones. Spring
               Source DM Server y TC Server son un claro ejemplo de estas funcionalidades.

Frameworks
               Gestión de transacciones y seguridad son habitualmente implementadas mediante aspectos. Asimismo,
               otras utilizaciones de los aspectos podría ser la inyección de dependencias en objetos de dominio.
               Para obtener un amplio abanico de posibilidades de uso de los aspectos, el lector podría visitar los
               proyectos de Spring Roo o Apache Magma.

Herramientas de monitorización
               El uso de aspectos facilita también la construcción de herramientas de monitorización. Muchas
               herramientas utilizan AspectJ como tecnología subyacente: Glassbox,Perf4J,Contract4J,JXInsight o
               MaintainJ son algunos de los ejemplos.

Compiladores e integración de IDE's
               El mismo equipo de AspectJ utiliza la propia tecnología para extender el compilador de JDT de manera
               que sea capaz de sopotar las nuevas construcciones. AJDT utilizan un proceso de weaving a través de
               una implementación basada en OSGI ofrecida por el proyecto Equinox. Scala IDE en Eclipse utiliza
               un enfoque similar para la construcción del entorno de desarrollo.2


Introducción a AOP
               AOP se construye sobre metodologías existentes como OOP o programación funcional,
               mejorándolas con las construcciones necesarias que permiten modularizar correctamente los conceptos
               transversales. Por ejemplo, si se trabaja con OOP, el núcleo de nuestro sistema será implementado
               mediante la utilización de clases. Los aspectos serán los encargados de representar las funcionalidades
               transversales y determinar cómo todos los diferentes módulos deberán ser tejidos para construir el
               sistema final.

Metodología AOP
               Desarrollar un sistema utilizando AOP es similar a un desarrollo basado en otras metodologías:
               determinar los requerimientos, implementarlos y construir el sistema final mediante la combinación
               de los mismos. La comunidad AOP define tres pasos:

               1. Descomposición en aspectos En este paso se indentificarán los diferentes concerns , tanto los
                  transversales como los que componen el núcleo. Por ejemplo, en una capa de negocio encargada de
                  calcular el IVA total de los productos los aspectos pertenecientes al núcleo sería el cálculo del IVA
                  en sí, mientras que elementos como la transaccionalidad, registro de actividad,seguridad en hilos,
                  manejo de cachés, . . . serían conceptos de un espectro mucho más amplio, que serán necesitados
                  en otros muchos módulos del sistema, y por tanto, se categorizan como conceptos transversales

               2. Implementación de "concerns" En este punto tendrá que realizarse la implementación de los
                  diferentes requerimientos de manera independiente . Siguiendo con el ejemplo anterior, un grupo
2
 Ver la sección inicial de este capítulo




                                                            7
Aspect Oriented Programming


         sería el encargado de realizar la implementación del módulo de lógica de negocio encargado de
         calcular el IVA, otro grupo llevaría a cabo la gestión del logging, un tercer grupo sería el encargado
         de asegurarse que las operaciones fuesen thread safe , y así sucesivamente.

      3. Recomposición de aspectos . En este paso se deben definir las reglas de composición mediante la
         creación de módulos o aspectos . Este proceso, conocido como weaving , utiliza esta información
         para construir el sistema final.

      La principal aportación de AOP es la independencia de los "concerns" en el momento de su
      implementación. El modo en que se realiza la implementación permite una completa trazabilidad entre
      los requerimientos y su implementación, por lo que el sistema final será más fácil de comprender,
      implementar o adaptar ante futuros cambios


Anatomía de un lenguaje orientado a aspectos
      La orientación a aspectos es simplemente una metodología por lo que será necesario definir el lenguaje
      y ofrecer un conjunto de herramientas para trabajar con la misma. Al igual que otra metodología de
      programación, una implementación concreta de AOP constará de dos partes:

      • Especificación del lenguaje encargado de describir las construcciones y sintaxis que serán utilizadas
        en la construcción y el tejido de todos los "concerns", tanto los pertenecientes al núcleo como los
        transversales.

      • La implementación del lenguaje es la encargada de verificar la adherencia del código a la
        especificación del lenguaje y de trasladar el código a un ejecutable capaz de ser comprendido por
        una máquina. Esta tarea,habitualmente,es realizada por un compilador o un intérprete.

Especificación del lenguaje AOP
      Cualquier implementación de la metodología AOP requiere la definición de dos lenguajes: el primero
      de ellos permitirá realizar la implementación de los requisitos individuales mientras que gracias al
      segundo podremos definir las reglas que "tejen" el conjunto de módulos independientes.

      • Implementación de concerns .Al igual que en otras metodologías, los requisitos se implementan
        en módulos que contienen los datos y el comportamiento necesario para ofrecer sus servicios.
        Imaginemos por ejemplo que estamos construyendo el núcleo del concern de seguridad; dicho
        núcleo mantendrá un manager de control de accesos y una colección de elementos ( voters ).
        Habitualmente,tanto los concerns transversales como los del núcleo se implementan mediante la
        utilización de lenguajes estándar como pueden ser C++ o Java.

      • Especificación de reglas de "tejido". Las reglas de tejido especifican cómo debemos integrar los
        diferentes concerns que hemos implementado para componer el sistema final. El lenguaje utilizado
        para definir estas reglas puede ser una evolución del lenguaje natural o algo completamente
        diferente. Así por ejemplo, podríamos ofrecer una implementación de la metodología AOP en la que
        Java es el lenguaje base y la definición de reglas de tejido se realiza mediante un DSL implementado
        en Groovy .

Implementación de AOP
      La implementación del lenguaje debe llevar a cabo dos acciones:combinar los aspectos individuales
      mediante las reglas de tejido,para, posteriormente, convertir la información resultante en código
      ejecutable. El primero de los dos pasos anteriores es conocido como weaving, y el procesador
      encargado de realizar dicha tarea es el weaver.

      • Proceso de weaving . Tal y como argumentaba la introducción de este punto, el proceso de weaving
        es el encargado de componer el sistema final mediante la composición de los diferentes concerns
        siguiendo las pautas establecidas en las reglas de tejido . Estas reglas son definidas en aspectos




                                                   8
Aspect Oriented Programming


       independientes del núcleo del sistema por lo que con unas nuevas reglas de "tejido" podríamos
       construir un sistema final completamente diferente.

     • Procesador (Weaver) El procesador encargado de llevar a cabo el proceso de weaving descrito en
       el punto anterior es comunmente conocido como weaver

       Una posible implementación sería utilizar una transformación código a código (un compilador). De
       ese modo, el compilador de aop "tejería" los aspectos junto al resto de clases generando un nuevo
       código ya "tejido". Una vez finalizado este proceso, el código generado anteriormente serviría como
       entrada para el compilador de lenguaje base el cual sería el encargado de generar el ejecutable.
       Utilizando el enfoque anterior, una aproximación basada en C++ convertiría todos los archivos
       individuales (aspectos y clases) en código C++ tejido(weaving).

     El siguiente diagrama ilustra la aproximación descrita en el párrafo anterior:

     Figure 1.4. Proceso de generación del sistema final




Beneficios de la metodología AOP
     La mayoría de las críticas sobre AOP destacan que en muchas ocasiones es demasiado complejo.
     Evidentemente, es necesario un poco de tiempo y paciencia para conseguir ser un experto. Sin
     embargo, el motivo principal de su complejidad es que se trata de una tecnología relativamente nueva.

     Algunos de los beneficios más detacables de esta metodología son:

     • Responsabilidades claramente diferenciadas . Cada módulo es el responsable de su funcionalidad
       principal; dejando de lado los conceptos transversales. Así por ejemplo, un módulo cuyo principal
       cometido es implementar la lógica de acceso a datos de un sistema de ventas por internet, no tendrá
       que preocuparse de realizar pooling sobre la base de datos o de la transaccionalidad. Gracias a esta
       clara asignación de responsabilidades se consigue una alta trazabilidad entre los requisitos y su
       correspondiente implementación.

     • Incremento de la modularidad . Utilizando AOP se consigue manejar cada uno de los conceptos
       de manera independiente con un acoplamiento mínimo. Incluso aunque estén presentes conceptos
       transversales que afecten al sistema completo, la implementación es modular.

     • Retraso en las decisiones de diseño .Cuando se arquitecta un nuevo sistema siempre aparece el
       siguiente dilema: ¿se debe realizar un diseño sumamente complejo y detallado que intente abarcar
       todas las funcionalidades,incluso las futuras? o, por el contrario, ¿debe arquitectarse una solución
       que se corresponda con la situación actual?.

       Gracias a AOP, el arquitecto de la solución, puede retrasar la toma de determinadas decisiones de
       diseño dado que los futuros requerimientos se implementarán en aspectos independientes. Dando un
       paso más adelante, AOP conforma un gran equipo junto con una metodología ágil como puede ser



                                                 9
Aspect Oriented Programming


       XP (siglas en inglés de Programación Extrema) siguiendo la práctica del principio YAGNI (siglas
       en inglés de No lo vas a necesitar ) . De este modo, podemos seguir el principio anterior, dando
       vida únicamente a las funcionalidades requeridas e implementando futuros requerimientos sin la
       necesidad de grandes modificaciones en el sistema.

     • Sencillez en las mejoras . AOP permite añadir una nueva funcionalidad sin más que desarrollar un
       nuevo aspecto (el cual no afecta al núcleo del sistema). Gracias a ello, el tiempo de respuesta ante
       nuevos requerimientos disminuye notablemente.

     • Incremento en la reutilización del código .Puesto que AOP implementa cada aspecto en un módulo
       independiente, cada uno de ellos es independiente del resto. En general, cada uno de ellos no suelen
       tener conocimiento del resto de elementos que conforman el sistema final. Realmente, el único
       elemento consciente del acoplamiento entre los diferentes módulos son las reglas de tejido , de
       manera que, si cambiamos éstas, podemos componer un sistema final completamente diferente.

     • Reducción de costes y accesos al mercado más rápidos .Las características descritas en los
       puntos anteriores generan sistemas más rápidos, tanto en su desarrollo como en su implantación
       . Eliminando la necesidad de modificar múltiples módulos para la implementación de un
       nuevo concepto transversal, AOP provoca que dicha implementación sea más barata. Asimismo,
       permitiendo que los desarrolladores estén centrados en su especialidad logramos que el coste del
       desarrollo disminuya.

Verdades y mentiras sobre AOP
     En los últimos años AOP ha sufrido un gran crecimiento aunque,en algunas ocasiones, todavía se
     percibe demasiado complicado, tanto en su implementación como en su proceso de aprendizaje. A
     continuación veremos algunas hipótesis y los motivos por los que las mismas son consideradas ciertas
     o falsas:

     • AOP no soluciona nuevos problemas . Esta afirmación es completamente cierta. La orientación a
       aspectos no ofrece solución a problemas irresolubles sino que aporta soluciones más sencillas y
       elegantes a los problemas actuales. Al fin y al cabo, no hay nada que no podamos implementar con
       código máquina.

     • Flujos complicados de seguir . De nuevo esta afirmación es cierta. En muchas ocasiones, en
       función de la complejidad del sistema que estemos construyendo, el orden en el que se ejecutan las
       instrucciones puede resultar complicado de seguir.

       La afirmación anterior también es cierta para otras metodologías ajenas a AOP. En OOP, el uso
       del polimorfismo hace que analizar el flujo de ejecución de un programa no sea una tarea sencilla.
       Incluso en lenguajes procedimientales, como podría ser C, el uso de punteros a funciones dificulta
       las tareas de seguimiento del programa.

     • AOP promueve malos diseños . En esta ocasión la afirmación es falsa. Una aproximación orientada
       a aspectos no es la solución para un mal diseño sino que simplemente facilita nuevos modos de
       resolución de problemas en aquellas áreas en las que lenguajes procedimientales u orientados a
       objetos presentan carencias.

     • Los interfaces de las metodologías OOP son suficientes . De nuevo en esta ocasión, la
       afirmación anterior es falsa. La técnica descrita propone utilizar un interfaz e ir intercambiando las
       implementaciones subyancentes (nótese que esto no implica cambios en el API). Puede parecer a
       simple vista que esta solución es satisfactoria, pero dista mucho de ser así, puesto que necesitamos
       invocar al código en todos aquellos lugares en los que corresponda. Esta técnica sirve de gran
       ayuda (tanto en OOP como AOP), pero en ningún momento los interfaces son una alternativa a la
       orientación a aspectos.

     • AOP supone una ruptura de la encapsulación . Esto afirmación es cierta aunque con ciertos matices
       puesto que dicha ruptura se realiza de una manera controlada y sistemática. Las clases en OOP



                                                 10
Aspect Oriented Programming


       encapsulan todo el comportamiento, mientras que AOP elimina estos niveles de control de las
       mismas.

     • AOP reemplazará a OOP . Falso. Los conceptos principales seguirán siendo implementados en
       OOP ( o puede que en un lenguaje procedimantal como puede ser C). AOP añade un nuevo conjunto
       de conceptos adicionales a la metodología orientada a objetos. Efectivamente, AOP cambiará
       el modo en el que se utilizan las metodologías actuales para la implementación de conceptos
       transversales.


Visión general de AspectJ
     AspectJ es una extensión orientada a aspectos de propósito general al lenguaje Java. Puesto que es
     una extensión del lenguaje Java, cualquier programa escrito en dicho lenguaje es un programa AspectJ
     válido. Un compilador AspectJ genera archivos .class de acuerdo a la especificación del bytecode
     de Java de manera que cualquier implementación de la máquina virtual sea capaz de ejecutar dichos
     archivos.

     El lenguaje AspectJ , de acuerdo a los conceptos descritos en el apartado anterior, consta de dos
     partes: la especificación del lenguaje que define los conceptos principales implementados mediante
     clases Java, y las extensiones AOP que permiten realizar el tejido de los conceptos transversales. La
     implementación del lenguaje facilita herramientas como compiladores, depuradores e integración con
     la mayoría de IDE´s modernos.

     Los siguientes apartados servirán de introducción a AspectJ y algunos conceptos avanzados gracias a
     los cuales se podrá comenzar a escribir programas simples.


Introducción a AspectJ
     El compilador de AspectJ es el encargado de utilizar los módulos que contienen las definiciones de las
     reglas de tejido para añadir nuevo comportamiento a los módulos que implementan las funcionalidades
     principales. El proceso anterior no realiza ninguna modificación sobre el código fuente del núcleo
     dado que el proceso de tejido se realiza sobre el bytecode generado por el compilador.


Modelo de Joint Point
     El modelo de joint point (no vamos a traducir el término) está compuesto de dos partes claramente
     diferenciadas: los "join point", que no son más que puntos en la ejecución de un programa, y los
     "pointcuts", un mecanismo de selección de los puntos anteriores.

     Imaginemos por un momento que nos encontramos desarrollando un sistema que necesita gestión de
     la seguridad, algo muy común en el mundo en el que nos movemos, y, que, debido a la naturaleza
     transversal del mismo, elegimos AOP como enfoque principal de nuestra solución. ¿Cuáles son los
     pasos que deberíamos seguir?

     1. Identificar los puntos del sistema que necesitan ser protegidos, comprobando, antes de realizar el
        acceso, que el usuario está autenticado y tiene los privilegios necesarios para hacerlo.

        En resumen, estamos identificando los "joint point" que requieren ser securizados.

     2. Construiremos un pointcut (o varios, todos los que sean necesarios), que permita la selección de
        los "joint point" descritos en el punto anterior.

     3. Construiremos un aspecto que encapsule toda la lógica de seguridad requerida.

     Los conceptos anteriores son sumamente importantes dado que componen la base de AOP. Los
     siguientes subapartados profundizarán en cada uno de ellos.



                                                11
Aspect Oriented Programming


Joint Point
        Como ya se definió anteriormente, un join point es un punto de ejecución en un sistema. Así por
        ejemplo, el acceso al campo de una clase, la ejecución de una función o una sentencia for son ejemplos
        de join points.

        AspectJ solamente expone un subconjunto de todos los posibles joint points, limitando de este modo,
        el acceso a las construcciones más estables.

Pointcuts
        Es un artefacto que nos permite seleccionar joint points y recuperar su contexto.Veamos algunas de
        las características principales:

Selección de joint points
        Los pointcut especifican un criterio de selección. Utilizaremos tipos, campos, métodos, anotaciones,
        etc para generar dichas definiciones. También podremos establecer condiciones en tiempo de
        ejecución que tendrán que cumplirse en el joint point seleccionado.

Determinación del contexto
        Los joint point disponen de información en tiempo de ejecución. Determinados pointcuts pueden
        recolectar dicha información y pasársela al advice. Por ejemplo, la llamada a un método de un objeto
        tendrá disponible el propio objeto que realiza la llamada y los argumentos que se están pasando.

Utilización de signaturas
        En Java, todos los elementos que componente un programa tienen una signatura. La utilización de
        patrones para dichas signaturas permiten a los pointcuts especificar las reglas que permiten seleccionar
        los joint point deseados.

Categorías de joint points
        A continuación se verá un conjunto de categorías de joints points expuestas por AspectJ. A pesar de
        ser un número considerable de categorías, no se han incluido todas, sino aquellas que se utilizan con
        mayor frecuencia. Si el lector desea realizar una lectura más profunda aquí podrá encontrar todo lo
        que necesita: AspectJ Programming Guide [http://www.eclipse.org/aspectj/docs.php]

        Table 1.1. Categorías de joint points expuestas por AspectJ (resumen)
        Categoría                 Joint Point Expuesto      Código que representa
        Método                    Execution                 Cuerpo del método
        Método                    Call                      Invocación del método
        Constructor               Execution                 Ejecución de la lógica de creación de un objeto
        Constructor               Call                      Invocación de la lógica de creación de un objeto
        Acceso a un campo         Read                      Lectura de un objeto o el campo de una clase
        Acceso a un campo         Write                     Escritura de un objeto o el campo de una clase
        Proceso de excepciones Handler                      Bloque catch para manejar una excepción
        Inicialización            Class init                Proceso de carga de una clase (class loading)
        Inicialización            Object init               Inicialización de un objeto en un constructor
        Inicialización            Object pre-init           Pre-inicialización de un objeto en un constructor
        Advice                    Execution                 Ejecución de un advice




                                                    12
Aspect Oriented Programming


Conceptos básicos
        A continuación se analizarán los elementos básicos que se deben conocer para definir un pointcut.

Pointcuts anónimos o con nombre
        Se permite la declaración de pointcuts de cualquiera de los dos tipos. Los primeros son similares a
        las clases anónimas, y por tanto se definen en el lugar en el que se van a utilizar. En el caso de los
        segundos, podremos referenciarlos desde múltiples lugares, permitiendo de este modo su reutilización.

Operadores
        AspectJ proporciona el operador unario de negación (!) y dos operadores binarios: && y ||, gracias
        a los cuales se permite construir reglas de matching complejas mediante la combinación de pointcuts
        más sencillos.

        Tanto la semántica como la precedencia es la misma que en el lenguaje Java. Así por ejemplo,en
        el caso del operador binario &&, se seleccionarán aquellos joint points que concuerden con los dos
        pointcuts que actúan como operandos.

Signaturas: sintaxis y ejemplos
        Las signaturas son la base de la definición de los pointcuts. El lenguaje debe facilitar una manera
        sencilla que permita definir criterios de selección sobre los diferentes aspectos transversales que
        estamos implementando. En el caso de AspectJ, se utilizan expresiones regulares (wildcards) en
        combinación a las signaturas. Los siguientes wildcards son soportados:

        • * especifica cualquier número de caracteres, exceptuando el punto (.). En la signatura de un tipo,
          denota una parte de un tipo o de un paquete. En otros patrones denota una parte del nombre (por
          ejemplo en métodos o campos)

        • .. determina cualquier número de caractéres, incluyendo en este caso cualquier número de puntos
          (.). En la signatura de un tipo representa cualquier paquete o subpaquete. En la signatura de un
          método representa cualquier número de argumentos.

        • + denota cualquier subtipo de un tipo determinado.

        A lo largo de los siguientes subapartados veremos, a través de una serie de ejemplos, los diferentes
        patrones de signaturas ofrecidos por AspectJ que podemos utilizar para seleccionar dierentes joint
        points

Signaturas de tipos

        Table 1.2. Ejemplos de signaturas de tipos
        Patrón de        la Descripción                              Ejemplos de tipos concordantes
        signatura
        AstVisitor          El tipo AstVisitor                       Sólo el tipo AstVisitor concuerda (ni
                                                                     tipos base ni derivados)
        *AstVisitor         Cualquier tipo cuyo nombre termine en Por ejemplo, HighlightingAstVisitor o
                            AstVisitor                            SemanticAstVisitor concuerdan con el
                                                                  patrón
        java.*.Date         El tipo Date en cualquier subpaquete java.util.Date o java.sql.Date son
                            directo del paquete java             ejemplos de tipos concordantes
        javax..*            Cualquier tipo en el paquete javax y en Cualquier tipo en el paquete
                            sus subpaquetes (tanto directos como javax.security así como cualquiera
                            indirectos)                             de sus subpaquetes indirectos como
                                                                    javax.security.auth.login




                                                   13
Aspect Oriented Programming


        Patrón de       la Descripción                               Ejemplos de tipos concordantes
        signatura
        javax..*Model      Todos los tipos en el paquete javax TableModel, TreeModel y sus
                           (subpaquetes directos e indirectos) subtipos como DefaultTreeModel o
                           cuyo nombre termine en Model, y todos DefaultTableModel.
                           los subtipos de estos.

Singaturas de tipos: anotaciones

        Table 1.3. Ejemplos de signaturas de tipos: anotaciones
        Patrón de       la Descripción                               Ejemplos de tipos concorndantes
        signatura
        @Secured User      El tipo User anotado con la anotación @Secured class User{. . .}
                           Secured
        @Entity *          Cualquier tipo anotado con la anotación @Entity class Section {. . .},@Entity
                           Entity                                  class Report {. . .}
        @Transactional*    El tipo Manager y cualquiera de sus       @TransactionalDefault        class
        Manager+           clases derivadas que estén anotados con   Manager{},@TransactionalOracle
                           una anotación cuyo nombre comienze        class   OracleManager     extends
                           por Transactional                         Manager{}

Signaturas de tipos: generics

        Table 1.4. Ejemplos de signaturas de tipos: generics
        Patrón de       la Descripción                               Ejemplos de tipos concordantes
        signatura
        Map                El tipo Map cuyo primer argumento En este caso únicamente concordará el
        <Integer,String>   genérico está fijado a Integer y el tipo Map<Integer,String>
                           segundo a String
        *<User>            Cualquier tipo genérico cuyo único Collection<User>,List<User>, . . .
                           argumento genérico sea de tipo User
        Collection<?       El tipo Collection con un parámetro de Collection<User>,
        extends User>      tipo User o derivado                   Collection<DomainUser>, . . .
        Collection<?       El tipo Collection, cuyo parámetro será Collection<Serializable>,
        super User>        uno de los tipos base de User           Collection<BaseUser>,        asumiendo
                                                                   que, User extiende o implementa,
                                                                   directa o indirectamente, Serializable y
                                                                   BaseUser

Combinando pointcuts: operadores

        Table 1.5. Signaturas de tipo: operadores
        Patrón de       la Descripción                               Ejemplos de tipos concordantes
        signatura
        !Collection        Cualquier tipo excepto Collection         User,Model, List (aunque sea subclase
                                                                     de Collection)
        Set || Map         Los tipos Set o Map                       Los tipos Set y Map únicamente
        !@Transactional    Cualquier tipo que se encuentre anotado class NonTransactionalManager{}
                           por por la anotación Transactional
        @Serializable      Cualquier tipo que se encuentre anotado @Serializable @Encrypted           class
        @Encrypted *       por las dos anotaciones                 UserCredentials{}




                                                 14
Aspect Oriented Programming


        Patrón de              la Descripción                               Ejemplos de tipos concordantes
        signatura
        (@Serializable || Cualquier tipo que esté anotado por @Serializable class User {}
        @Encrypted) *     alguna de las dos anotaciones

Signaturas de métodos y constructores

       Table 1.6. Signaturas de métodos
        Patrón de              la Descripción                               Ejemplos de métodos concordantes
        signatura
        public       void Cualquier método público de la clase class User{ public void setName(String
        User.set*(*)      User cuyo nombre comienze por set, name){} }
                          cuyo tipo de retorno sea void, y que
                          espere un único argumento
        public           void Cualquier método público de la clase class User { public void updateInfo()
        User.*()              User cuyo tipo de retorno sea void y que {}}
                              no espere argumentos
        public * User.*()        Cualquier método público de la clase class User{ public                UserInfo
                                 User que no espera argumentos y getUserInfo(){}}
                                 retorna cualquier tipo
        public * User.*(..) Cualquier método público de la clase            class    User{    public   UserInfo
                            User que retorna cualquier tipo, y              getUserInfo(){},public         Date
                            espera cualquier número y tipo de               updatesBetween(Date first,Date last)
                            argumentos (incluido cero)                      {}}
        * *.*(..) o * * (..)     Cualquier método independiente de su Cualquier método del sistema
                                 tipo, del tipo de retorno, de su nombre
                                 y de los argumentos que espere
        !public * User.*(..) Cualquier método que no sea público class User {protected getUserInfo(){}}
                             (privado,protegido o paquete)
        * * (..) throws Cualquier método que declare que clas AntlRBasedParser {                           public
        RecognitionException
                          puede lanzar una excepción de tipo void parser(String file)                     throws
                          RecognitionException               RecognitionException}
        * User+.*(..)            Cualquier método en la clase User y sus class UserDetails extends User {}
                                 subclases
        User                     Cualquier método del tipo UserService      class    UserService{public      User
        UserService.*(..)        cuyo tipo de retorno sea User. Si alguna   retrieveUser(String name){}} class
                                 de las subclases sobreescribe el tipo      DetailUserService             extends
                                 de retorno con un subtipo de User          UserService{public       DetailedUser
                                 (mediante el tipo de retorno covariante    retrieveUser(String name){}}
                                 introducido en Java 5) también será
                                 seleccionado.

       La signatura en el caso de los constructores difiere de la signatura de métodos en los siguientes
       aspectos:

       • Los constructores no tienen tipo de retorno por lo que no se permite utilizar el valor de retorno en
         la especificación de un pointcut de este tipo.

       • Dado que los nombres de los constructores no pueden ser libres (tienen que utilizar el mismo nombre
         de la clase), la parte de la signatura destinada al nombre será sustituida con la palabra new.

       • Por último, puesto que los constructores no pueden ser estáticos, no se podrá utilizar la palabra
         reservada static




                                                       15
Aspect Oriented Programming


Signaturas de campos

       Table 1.7. Signaturas de campos de clase
        Patrón de        la Descripción                              Ejemplos de campos concordantes
        signatura
        private    String Campo privado (tanto campo de una class User { private String username;}
        User.username     instancia como estático) de la clase
                          User
        * User.*            Cualquier campo de la clase User class           User{private        String
                            independiente de sus cualificadores, username;protected int credits;private
                            tipo y nombre.                       UserDetails details;}
        * User+.*           Cualquier        campo       de   la El ejemplo de la fila anterior o class
                            clase     User       y    todas  sus SpecificUser extends User {private
                            subclases, independientemente de sus String address;}
                            cualificadores, tipo y nombre.

Implementación de pointcuts
       AspectJ ofrece dos mecanimos diferentes que permiten a los pointcuts realizar la selección de los joint
       points

       • Kinded pointcuts. En este caso, los pointcuts seleccionan categorías de joint points (de ahí su
         nombre). Así, por ejemplo, se ofrece la posibilidad de realizar matching sobre la ejecución de un
         método

       • Non-kinded pointcuts. Se seleccionan los joint point en base a la información de la que disponen,
         como los tipos en tiempo de ejecución o su contexto. En esta situación se seleccionan joint points
         de cualquier clase, siempre y cuando sastisfagan la condición descrita

       De nuevo, al igual que en el apartado anterior, veremos las diferentes opciones disponibles, tanto para
       los kinded como para los non-kinded pointcuts.

Kinded pointcuts

       Table 1.8. Joint Points expuestos y tipos de pointcuts
        Categoría de Joint Point                           Sintaxis del pointcut
        Ejecución de un método                             execution(MethodSignature)
        Llamada a un método                                call(MethodSignature)
        Ejecución de un constructor                        execution(ConstructorSignature)
        Llamada a un constructor                           call(ConstructorSignature)
        Inicalización de una clase                         staticinitializaction(TypeSignature)
        Acceso de lectura a un campo                       get(FieldSignature)
        Acceso de escritura a un campo                     set(FieldSignature)
        Ejecución de un manejador de excepciones           handler(TypeSignature)
        Inicialización de un objeto                        initialization(ConstructorSignature)
        Pre-inicialización de un objeto                    preinitialization(ConstructorSignature)
        Ejecución de un advice                             adviceexecution()

       Por ejemplo, si deseamos seleccionar todas las llamadas a los métodos públicos commit() de la clase
       TransactionManager, escribiríamos un pointcut similar al siguiente:

       call(public void TransactionManager.commit(. .))




                                                   16
Aspect Oriented Programming


Non-kinded pointcuts
         Este tipo de pointctus permiten la selección de joint points basados en criterios adicionales a las
         signaturas vistas anteriormente. Por ejemplo, podremos seleccionar todos los joint point donde el
         objeto this es de un determinado tipo. Dicho joint point incluiría las llamadas a métodos, ejecuciones,
         manejadores de excepciones, etc.

         De nuevo, a través de ejemplos, veremos los diferentes tipos de non-kinded pointcuts ofrecios por
         AspectJ

Non-kinded pointcuts basados en control de flujo

         Table 1.9. Non-kinded pointcuts basados en control de flujo
          Pointcut                           Descripción
          cflow(execution(*                  Selecciona todos los joint points en el flujo de la ejecución de
          TransactionManager.commit()))      cualquier operación commit de la clase TransactionManager,
                                             incluyendo la ejecución del propio método.
          cflowbellow(execution(*            Selecciona todos los joint points en el flujo de la ejecución de
          TransactionManager.commit()))      cualquier operación commit de la clase TransactionManager,
                                             excluyendo la ejecución del método.
          cflow(execution(@Secured * * Todos los joint points en el flujo de la ejecución de cualquier
          (..)))                       método anotado con la anotación Secured
          cflow(transacted())                Cualquier joint point en el flujo de ejecución de los joint points
                                             seleccionados por el pointcut transacted()

Non-kinded pointcuts basados en la estructura léxica

         Dentro de este tipo de pointcuts tenemos dos categorías:

         • within(TypeSingnature): selecciona cualquier joint point que aparece en el cuerpo de las clases y
           aspectos que concuerden con el tipo especificado.

         • withincode(ConstructorSignature),withincode(MethodSignature): selecciona cualquier joint point
           que aparezca dentre de un método o un constructor, incluendo la definición de cualquier clase local
           que puediera aparecer en los mismos.

         Table 1.10. Non-kinded pointcuts basados en la estructura léxica
          Pointcut                           Descripción
          within(User)                       Selecciona todos los joint points que aparecen dentro de la clase
                                             User
          within(User+)                      Selecciona todos los joint points que aparecen dentro de la clase
                                             user y cualquiera de sus clases derivadas
          within(@Transactional *)           Selecciona todos los joint points que aparecen dentro de cualquier
                                             clase que se encuentre marcada con la notación Transactional
          withincode(*                      Selecciona todos los joint points que parecen dentro de cualquier
          TransactionManager.retrieve*(..)) método de la clase TransactionManager cuyo nombre comience
                                            por retrieve

Non-kinded pointcuts de ejecución

         Este tipo de pointcuts nos permiten seleccionar joint points en base al tipo de los objetos en tiempo
         de ejecución. De este modo, disponemos de:

         • this(). Acepta dos formas diferentes: this(ObjectIdentifier) o this(Type). Seleccionará aquellos joint
           points cuyo objeto this sea del tipo (o el objeto) indicado.




                                                     17
Aspect Oriented Programming


              • target(). Similar al concepto anterior, aunque en este caso, se utilizar el target del joint point en
                lugar del this

              Table 1.11. Pointctucts basados en la ejecución
               Pointcut                 Descripción
               this(User)               Selecciona cualquier joint point en que se la expressión this instanceof User sea
                                        cierta. Así por ejemplo, seleccionará las llamadas a métodos o accesos a campos
                                        donde el objeto actual sea de tipo User o cualquier de sus subclases.
               target(User)             Selecciona cualquier joint point en el que el objeto sobre el que se realiza la
                                        llamada al método es instanceof User

Non-kinded pointcuts sobre argumentos

              Este tipo de pointcuts nos permiten seleccionar joint points en base al tipo de los argumentos en tiempo
              de ejecución. Veamos los distintos tipos de argumentos, en función del tipo del joint point :

              • En el caso de los joint points manejadores de excepciones el argumento será la excepción manejada.

              • En los métodos y constructores, los argumentos serán los argumentos del método y constructor

              • Los accesos de modificación de un campo, el argumento será el nuevo valor que va a tomar dicho
                campo.

              Table 1.12. Ejemplos de pointctucts basados en argumentos
               Pointcut                 Descripción
               args(User, . . , Selecciona cualquier joint point de tipo método o constructor en el que el primer
               String)          argumento es de tipo User (o cualquiera de sus subclases), y el último argumento
                                es de tipo String.
               args(SqlException) Selecciona cualquier joint point con un único argumento de tipo SqlException.
                                  Seleccionaría cualquier método o constructor que esperase un único argumento
                                  de tipo SqlException, un acceso de escritura a una campo estableciendo un nuevo
                                  valor de tipo SqlException, y también seleccinaría un manejador de excepciones
                                  de tipo SqlException

Non-kinded pointcuts condicionales

              Este tipo de pointcuts nos permiten seleccionar joint points basados en una expresión condicional

              Table 1.13. Ejemplos de pointcuts condicionales
               Pointcut                 Descripción
               if(debug)                Selecciona cualquier joint point donde el campo estático debug (en la definición
                                        del aspecto) toma el valor cierto

                                3
Crosscutting dinámico
              A lo largo de las secciones anteriores hemos analizado el modelo de joint point de AspectJ y la manera
              de defininir las reglas que nos permitan seleccionar aquellos joint points que sean de nuestro interés.
              Durante este capítulo analizaremos el modo en el que podemos alterar el comportamiento de nuestro
              sistema en los joint points que hayamos seleccionado mediante la definición de nuestros pointcuts.

Descripción general
              Las reglas de tejido están compuestas de dos partes:
3
 El término crosscuting representa la naturaleza transversal de las funcionalidades que estamos añadiendo. Se ha optado por no realizar la
traducción del término y utilizar la terminología orginal




                                                                   18
Aspect Oriented Programming


        • advice: qué deseamos hacer

        • pointcuts: donde aplicamos el advice anterior

        AspectJ soporta el crosscutting dinámico mediante los advices, construcciones similares a los métodos
        que nos permiten definir las acciones que a ejecutar en los joint points seleccionados por un pointcut.

Categorías de advices
        Dependiendo de las funcionalidades que estemos implementando necesitaremos ejecutar nuestra
        lógica en un determinado lugar del flujo de ejcución orginal; así por ejemplo, si estamos construyendo
        la seguridad de un sistema, nuestro código tendrá que verificar dicha seguridad antes de la ejecución del
        joint point. Si estuvieramos construyendo un sistema de cachés, nuestra nueva funcionalidad tendría
        que ejecutarse alrededor de joint point original, intentando recuperar el valor de la caché, y en caso de
        que no exista, ejecutar el código real y añadirlo a la misma para futuras invocaciones. AspectJ ofrece
        tres categorias de advices que satisfacen los escenarios anteriores (y alguno más):

        • Before Advice se ejecutan anteriormente a la ejecución del joint point

        • After Advice: se ejecutan posteriormente a la ejecución del joint point. Existen tres variantes
          diferentes

          • After finally se ejecuta tras la ejecución del join point independientemente del resultado de dicha
            ejecución

          • After returning se ejecuta tras la ejecución del joint point siempre y cuándo ésta última haya
            finalizado correctamente, es decir, sin lanzar ninguna excepción.

          • After throwing se ejecuta tras la ejecución fallida de un joint point, es decir, después de que dicho
            joint point dispare una excepción.

        • Around Advice rodean la ejecución del joint point.

Sintaxis de los advices
        Aunque la sintaxis varía ligeramente dependiendo del tipo de advice que estemos escribiendo,
        podríamos dividir su estructura general en tres partes claramente diferenciadas:

        • Declaración del advice. En esta parte de la declaración se especifica el momento de ejecución del
          advice, es decir, si se ejecutará antes, después y alrededor de los joint points

        • Definición de los pointcuts. Se especifican los pointcuts sobre los que se desea actuar.

        • Cuerpo del advice. Definición del código a ejecutar una vez se haya alcanzado el joint point
          indicado.

        Veamos un ejemplo sencillo de definición de un advice:

        En primer lugar defininamos un sencillo pointcut


        pointcut secureOperation(User user):
         call( * User.*(..)) && target(user)

        En el pointcut anterior estamos capturando todas las llamadas a cualquier método de la clase User, y,
        adicionalmente estamos recogiendo el objeto que actua como target de la llamada.

        A continuación veremos un around advice para ilustrar la sintaxis:

        Object around(User user):secureOperation(user){
         System.out.println("Securing operation on user "
              + user.toString());




                                                    19
Aspect Oriented Programming


         Object retValue = proceed(user);
         System.out.println("Finished secured operation on user "
              + user.toString());
         return retValue;
        }

        En la definición anterior podemos ver la estructura de la declaración de un advice descrita
        anteriormente

        1. La parte que precede a los dos puntos indica el momento de ejecución del advice
           (after,before,around). En este caso, se ejecutará alrededor del joint point seleccionado.

        2. La parte que sigue a los dos puntos representa el pointcut, es decir, la definición de los criterios
           que determinan cuando se ejecutará el advice

        3. La última parte representa el cuerpo del advice, es decir, el código que se ejecutará cuando alguno
           de los joint point definidos por el pointcut sea alcanzado.

Advices y métodos
        Al igual que los métodos de una clase, los advices se utilizan para definir comportamiento. La sintaxis
        de éstos últimos es similar a la de los métodos aunque existen algunas diferencias dado que los advices
        son aplicados de manera automática, sin la necesidad de realizar explicitamente la invocación del
        mismo.

Similitudes
        Analizemos las similitudes de ambos en tres categorías diferentes: declaración, cuerpo y
        comportamiento.

        La declaración de un advice es similar a la signatura de un método tradicional:

        • Opcionalmente puede asigarse un nombre al advice mediante el uso de la anotación @AdviceName

        • Recibe argumentos a través del contexto del joint point, que posteriormente podrán ser utilizados
          en el cuerpo para implementar la lógica necesaria.

        • Puede declarar el lanzamiento de una excepción.

        En cuerpo de los advices también es muy parecido al de los métodos:

        • El código del cuerpo del advice sigue las mismas reglas de acceso a miembros de otros tipos y/
          o aspectos.

        • Se puede referenciar a la propia instancia del aspecto mediante el uso de this,

        • Los advices de tipo around pueden retornar un valor.

        • Los advices deben declarar las excepciones que sean checked que la implementación podría
          disparar.

        En el caso de los métodos, los advices :

        • No pueden declarar el disparo de una excepción que no está declarada en TODOS los joint points
          sobre los que actua

        • Pueden omitir algunas de las excepciones de tipo checked que han sido declaradas por alguno de
          los joint point sobre los que actua.

        • Pueden declarar el disparo de excepciones más específicas (de tipo checked) que las definidas por
          los joint point sobre los que está actuando.

        • Pueden lanzar cualquier tipo de excepción de tipo runtime.




                                                    20
Aspect Oriented Programming


Diferencias
         En comparación con los métodos, los advices:

         • La declaración de un nombre es opcional.

         • No pueden ser invocados directamente.

         • No presentan especificadores de acceso (relacionado con la característica de que no pueden ser
           invocados directamente)

         • No presentan un tipo de retorno en los advices de tipo before y after

         • Tienen      acceso      a    unas      cuantas     variables    en     el           propio      aspecto:
           thisJointPoint,thisJointPointStaticPart,thisEnclosingJointPointStaticPart

         • Se puede utilizar la palabra reservada proceed en los advices de tipo around para ejecutar el joint
           point sobre el cual se está realizando el advice.

Análisis detallado de los advices
         Hasta este momento disponemos de la información sobre las diferentes categorías de advices y su
         sintáxis general. A lo largo de las siguientes subsecciones profundizaremos en cada uno de los
         diferentes tipos de advices.

Before advice
         Este tipo de advices se ejecutan antes de la ejecución del joint point sobre el que actúan. En el siguiente
         ejemplo:

               before():execution(@Secured * * (..)){
                 // asegurarse de que el usuario puede realizar la operación
               }

         el advice realiza una comprobación de seguridad antes de que se produzca la ejecución de cualquier
         método anotado con Secured.

         En caso de que el advice dispare una excepción, el joint point no se ejecutará. Este tipo de aspectos
         son comunmente utilizados en aspectos tales como seguridad o trazabilidad.

After advice
         Se ejecutan después de la ejecución del joint point sobre el que actuan. Dentro de esta categoría,
         AspectJ ofrece tres tipos de advices:

         • Ejecución del advice independientemente del resultado de la ejecución del joint point.

         • Ejecución del advice única y exclusivamente si el joint point ha finalizado correctamente.

         • Ejecución del advice después que el joint point haya disparado una excepción.

         Veamos en detalle cada uno de los tres tipos anteriores:

Advice After

         Este tipo de advices se ejecutan independientemente del resultado de la ejecución del joint point
         sobre el que actúan. Habitualmente se conoce a este tipo de advices como after finally puesto que su
         semántica es similar a la de un bloque finally.

         El siguiente advice:

         after(): call(@Logging * ServiceManager.*(..)){
         // registrar el resultado de la operación




                                                      21
Aspect Oriented Programming


         }

         registra el resultado de todas las operaciones de la clase ServiceManager que estén marcadas con la
         anotación Loggin, independientemente si retornan correctamente o terminan su ejecución de forma
         inesperada mediante el disparo de una excepción.

Advice After Returning

         En muchas ocasiones,será necesario ejecutar el código de nuestro advice única y exclusivamente
         cuando la ejecución del joint point haya terminado de forma correcta. Continuando con el ejemplo
         anterior:

         after () returning: call(@Logging * ServiceManager.*(..)){
         // registrar el resultado de la operación
         }

         se seguirá registrando el resultado de las operaciones, siempre y cuando, la ejecución haya terminado
         correctamente, sin el disparo de ninguna excepción.

         AspectJ ofrece una pequeña variante para este tipo de advices:


         after() returning (ReturnType returnObject)

         gracias a la cual se permite recuperar el objeto retornado por la ejecución del joint point dentro del
         advice. Veamos un pequeño ejemplo ilustrativo:


         after() returning (java.sql.Connection connection):
             call(java.sql.Connection DriverManager.getConnection(..)){
           System.out.println("Se ha recuperado la conexión " + connection);
         }

         Es importante tener claro que no se puede retornar un objeto nuevo (si que lo podemos modificar,
         pero no retornar uno nuevo).

Advice After Exception

         Este tipo de advices son similares a los descritos en el apartado anterior. En este caso, el advice se
         ejecutará única y exclusivamente cuando el joint point dispare una excepción. Presentan la siguiente
         estructura:

         after() throwing:execution (* ServiceManager+.*(..))

         El advice del ejemplo anterior se ejecutará siempre y cuando algún método de la clase ServiceManager
         (o alguna de sus subclases), dispare una excepción. En el supuesto de que la ejecución del joint point
         termine correctamente, este tipo de advices no serán ejecutados.

         Al igual que los advices del apartado anterior, AspectJ ofrece una modo de recuperar la excepción que
         ha sido disparada por el joint point de modo que esté disponible en el cuerpo del advice. Siguiendo
         una sintáxis similar a la anterior, tendríamos:

         after() throwing (ExceptionType exceptionObject):

         Un after throwing advice nunca podrá tragarse la excepción;por lo que seguirá subiendo por la pila de
         llamadas hasta llegar al objeto que realizó la invocación del joint point.

Around advice
         Este clase de advices engloban al joint point, pudiendo ejecutar la lógica del mismo un número
         indefinido de veces. Incluso pueden omitir la ejecución del propio joint point. Algunos de los usos
         principales de este tipo de advices son los siguientes:




                                                    22
Aspect Oriented Programming


          • Ejecución de lógica adicional antes y después de la ejecución de un joint point, como por ejemplo,
            acciones de profiling.

          • Omitir la ejecución original, y realizar otra en su lugar, como por ejemplo, operaciones con cachés.

          • Envolver la operación con una gestión de excepciones, con el objetivo de aplicar una política de
            gestión de excepciones. Un ejemplo de este uso sería la gestión de transacciones.

          Este advice ofrece una potencia superior a todos los advices vistos hasta el momento, puesto que
          podrían sustituir a los anteriores. De todos modos, se considera una buena práctica utilizar el advice
          más sencillo que cumpla las necesidades de la tarea que necesitamos llevar a cabo.

Ejecución del joint point

          Si desde el around advice deseamos llevar a cabo la ejecución del joint point, tendremos que hacer uso
          de la palabra reservada proceed() dentro del cuerpo del advice. Debemos recordar, que, puesto que la
          invocación de proceed() ejecuta el joint point, tendremos que pasarle el mismo número de argumentos
          que han sido recolectados por el advice.

          Asimismo, puesto que la invocación de proceed() supone la ejecución del joint point, el valor de
          retorno será el retornado por éste último.

          Veamos un pequeño ejemplo de utilización de advices de este tipo:

          void around(User user,int credits) throws InsufficientCreditsException:
              call(* User.pay*(int)) && target(user) & & args(credits){
               try
               {
                 proceed(user,credits);
               }catch(InsufficientCreditsException ex){
                 if(!processException()){
                   throw ex;
                 }
               }

          Analicemos en detalle la construcción anterior:

          1. El pointcut selecciona cualquier llamada a los métodos de la clase User cuyo nombre comienze por
             pay y disparen una excepción de tipo InsufficientCreditsException

          2. La segunda parte del pointcut recolecta el contexto del joint point: el usuario sobre el que se está
             realizando la llamada y el número de créditos que se están pasando como argumento del método
             que se está ejecutando.

          3. En el cuerpo del advice, se engloba la ejecución del método con un bloque de gestión de
             excepciones, para realizar una protección adicional en caso de que se produzca una excepción. En
             el caso de que la protección adicional no sea correcta, la excepción será disparada de nuevo.

Retornando valores

          Todos los around advices deben declarar un valor de retorno (puediendo ser void). Habitualmente el
          tipo de retorno de éstos se corresponde con el tipo de retorno de los joint points sobre los que está
          actuando.

          En algunas ocasiones, todos los joint points sobre los que actua el advice no presentan el mismo tipo de
          retorno, como puede ocurrir cuando estamos añadiendo soporte transaccional a diferentes operaciones.
          En estas situaciones el tipo de retorno que debe declarar el advice será Object. AspectJ acomodará el
          valor de retorno de acuerdo a las siguientes reglas:

          • Si se está retornando un tipo primitivo, AspectJ realizará el boxing/unboxing correspondiente. Esta
            característica es similar a la incluida a partir de Java 5, pero AspectJ no precisa de dicha versión
            de Java para realizar la operación.




                                                      23
Aspect Oriented Programming


               • En el caso en el que el tipo de retorno no sea primitivo, AspectJ realizará los casts oportunos antes
                 de retornar el valor.

Contexto del joint point
               Muchas ocasiones es necesario acceder a los objetos que conforman la ejecución del joint point para
               que el advice pueda llevar a cabo la lógica correspondiente. Por tanto, los pointcuts, necesitan exponer
               el contexto disponible en la ejecución del joint point de modo que pueda estar disponible en el cuerpo
               del advice. Dicho contexto puede definirse de dos modos diferentes:

               • Objetos (incluyendo los tipos primitivos) que conforman el joint point

               • Anotaciones asociadas al joint point

               La siguiente tabla describe el cojunto de pointcuts que AspectJ ofrece para recuerar el contexto en
               los joint points.

               Table 1.14. Pointcuts para recuperar el contexto en un joint point
                Pointcut                        Contexto recuperado
                this(obj)                       Objecto this en el joint point que se está ejecutando
                target(obj)                     Objetivo de la llamada en el joint point que se está ejecutando. En el caso
                                                de un joint point de una llamada a un método, el target será el objeto que
                                                realiza la llamada. Para la ejecución de un método, el target será el objeto
                                                this. En los accesos a campos, el target será el objeto que se está accediendo.
                                                En el resto de joint points no existen un target disponible
                args(obj1,obj2,...)             Objetos que representa los argumentos en el joint point. Para las llamadas/
                                                ejecuciones de métodos/constructores, recupera los argumentos de los
                                                mismo. En el caso de los manejadores de excepciones, recupera la
                                                excepción producida. Para los accesos en modo escritura a un campo,
                                                recupera el nuevo valor del campo.
                @this(annot)                    Anotación asociada con el tipo del objeto this del joint point
                @target(annot)                  Anotación asociada con el tipo del objeto target del joint point
                @args(annot1,annot2,...)Anotación asociada con el tipo de los argumentos del joint point
                @within(annot)                  Anotación asociada con el tipo "enclosing" del joint point
                @withincode(annot)              Anotación asociada con el método "enclosing" del joint point
                annotation(annot)               Anotación asociada con el asunto actual del joint point.


Aspectos
               Los aspectos representan la únidad básica de modularización en el mundo de la orientación a aspectos
               en general, y en AspectJ, en particular. Los siguientes subapartados nos mostrarán una definición más
               formal que la vista hasta este momento.4

               Analizaremos en detalle los aspectos, realizaremos una comparativa con las clases y veremos como
               nos pueden ayudar a modularizar y construir componentes reutilizables.

Trabajando con aspectos
               Los aspectos son las construcciones encargadas de encapular la implementación de todos los conceptos
               transversales. Será el weaver el encargado de modificar el comportamiento del núcleo del sistema en
               función de la información definida en nuestros aspectos.
4
 Seguiremos analizando los nuevos conceptos, al igual que en las secciones anteriores, desde elpunto de vista de la sintaxis tradicional, dejando
un poco de lado la sintaxis @AspectJ




                                                                      24
Aspect Oriented Programming


             La sintaxis general de un aspecto es la siguiente:


             [access specification][abstract] aspect <AspectName>
             [extends class or aspect] [implements interface-list]
             [ [<association-speficier>(Pointcut)] |
                 [pertypewithin(TypePattern) ] ]{
               // aspect body
             }

             La palabra reservada aspect permite realizar la declaración de un nuevo aspecto. Cada uno de estos
             aspectos presenta las siguientes características:

             • Presenta un nombre para podere referirse a él desde otras partes del código.

             • Puede presentar especificadores de acceso (public,proteced o private)

             • Puede ser abstract

             • Puede aplicar el mecanismo de herencia, derivando de otros aspectos o de clases tradicionales.
               Asimismo puede implementar interfaces.

             • Puede especificar el modelo de instanciación

             • Su cuerpo puede estar compuesto por definiciones de pointcuts, miembros o tipos anidados.

Diferencias con las clases
             A la vista del apartado anterior, en un principio, parece que las clases y los aspectos son prácticamente
             lo mismo, pero no es así, los aspectos no son clases. A continuación se describen algunas de las
             diferencias principales:

Modelo de instanciación

             Es el sistema el encargado de la instanciación de los aspectos. En resumen, nunca utilizaremos la
             palabra reservada new para crear una instancia de un aspecto

Restricciones en el mecanismo de herencia

             Los aspectos no pueden derivar de otros aspectos concretos, es decir, sólo pueden derivar de aspectos
             definidos como abstract. Esto es una restricción que se incluyó en la definición del lenguaje para
             evitar complejidades innecesarias.

Parámetros genéricos

             Los aspectos concretos no pueden declarar parámetros genéricos, sólo aquellos marcados como
             abstract podran hacerlo. El motivo es el modelo de instanciación, puesto que, como los aspectos son
             instanciados por el sistema, éste último no es capaz de realizar la inferencia de tipos.

privileged

             Los aspectos pueden ser definidos con el especificador de acceso privileged, el cuál otorga la capacidad
             de acceder a los miembros privados de las clases sobre las que se está actuando.

Resumen
             Nos hemos introducido en el mundo AOP, hemos analizado su evolución a lo largo a lo largo del Hype
             Cycle, visto sus usos en el mundo real y hemos realizado un estudio de sus principales componentes
             y el modo en el que se utilizan cada uno de ellos.




                                                         25
Aspect Oriented Programming


               Evidentemente, esto pretende ser un primer acercamiento al mundo de AOP, y concretamente a
               AspectJ, a través del cual el lector pueda comprender los beneficios de esta tecnología y le permita
               utilizarlo para escribir sus propios programas. Soy consciente de que se han quedado muchas cosas en
               el tintero, que darían cabida para un libro completo, por lo que a continuación se enumeran algunas
               de ellas para las mentes inquietas que deseen profundizar en otros aspectos que no tienen cabida en
               este documento:

               • Técnicas como static crosscutting tales como:

                  • Introducción de nuevos miembros en una clase

                  • Complemento de anotaciones

                  • Modificación de jerarquías de tipos

                  • Respuesta a errores y warnings en tiempo de compilación

                  • Debilitado de excepciones

               • Asociación y predencia de aspectos

               • Sintáxis @AspectJ

               • Análisis detallado de los procesos de weaving

               • Integración con Spring

               • ...

               Para una análisis exhaustivo de estos y otros muchos aspectos, el usuario puede acudir a la sección
               bibliografía

               El objetivo de este introducción no era dar una visión teórica y aburrida de AspectJ sino dar una visión
               pragmática del mismo. De este modo, la siguiente sección ilustrará la mayoría de conceptos vistos
               anteriormente mediante una serie de ejemplos reales.

Ejemplos reales
               Hasta este momento hemos visto las posibilidades que nos ofrece AOP en general, y AspectJ en
               particular, mediante la exploración de sus elementos, sintáxis y ejemplos sencillos. Los siguientes
               subapartados ofrecerán un conjunto de ejemplos reales de aplicación de la tecnología así como algunos
               patrones habituales.

               La estructura de los ejemplos será la siguiente: se planteará un problema, se dará una solución general,
               y después se propondrá una alternativa basada en AOP y AspectJ. Pongámonos manos a la obra.
                                     5
Patrón wormhole
               Este patrón consiste, básicamente, en habilitar un contexto de información desde un llamante a un
               llamado sin la necesidad de pasar dicha información como un conjunto de argumentos a lo largo de
               todas las invocaciones del los diferentes métodos del flujo de ejecución. Imaginemos por un momento
               que estamos implementando un sistema de seguridad en el que cada uno de los métodos tiene que
               comprobar quien les ha invocado para determinar si se les permite ejecutar la operación.

               Creando un canal de comunicación directa entre dos niveles cualesquiera en la pila de llamadas,
               nos evitará tener que ir moviendo la información necesaria por cada una de las capas. De este
               modo, evitaremos la necesidad de modificar la cadena de llamadas cuando necesitemos añadir algún
               parámetro adicional al contexto de información.

5
 De nuevo, se ha optado por mantener la nomenclartura original del patrón, sin realizar una traducción al castellano, puesto que considero que
el resultado de dicha traducción no resultaría demasiado intuitiva para el lector.




                                                                     26
Aspect Oriented Programming


Solución tradicional
            Sin la utilización de una tecnología como AOP disponemos de dos alternativas de solución. La primera
            de ellas movería toda la información necesaria a lo largo del contexto de llamadas añadiendo los
            parámetros que fueran necesarios, mientras que la segunda, haría uso de un almacenamiento espefíco
            de los hilos.

            La solución que pasa a través de parámetros el contexto de información necesario produce una
            contaminación del API, puesto que cada uno de los métodos que intervienen en el flujo que
            transcurre desde el llamante hasta el llamado necesitará de parámetros adicionales que permitan mover
            dicha información a lo largo de la pila de llamadas. La segunda solución propuesta, el uso de un
            almacenamiento específico, pasaría porque el llamante crease una variable ThreadLocal en la que se
            almacenase toda la información necesaria. Aunque esta segunda solución evita la contaminación del
            API, se necesita modicar tanto el llamante como el llamado, además de requerir un conocimiento de
            cómo se almacena el contexto de información.

Descripción general
            La siguiente figura ilustra la idea básica de este patrón arquitectónico:

            Figure 1.5. Diagrama arquitectónico del patrón wormhole




            La idea general consiste en indentificar dos pointcuts: uno en el llamado y otro en el llamante. El
            primero de ellos será el encargado de recolectar toda la información que será transmitida a lo largo
            del "aguejero de gusano". El segundo pointcut tendrá que especificar aquellos joint point del llamado
            en los que debe actuar el wormhole.

            En la imagen anterior cada una de las cajas trasnversales representa un nivel en la pila de llamadas.
            Habitualemente, para comunicar el llamante y el llamado tendríamos que ir pasando toda la
            información de nivel en nivel, hasta que alcanzásemos el nivel deseado. El patrón descrito en esta
            sección establece un canal de comunicación directo a lo largo de todos los niveles de llamadas,
            evitando el paso de información nivel a nivel.

Plantilla
            A continuación se propone una plantilla de solución que puede ser utilizada como base para la
            implementación de este patrón en nuestros sistemas




                                                         27
Aspect Oriented Programming



 public aspect WormholeAspect {
  pointcut callerSpace(caller context) : <caller pointcut> ;

   pointcut calleeSpace(callee context) : <callee pointcut> ;

   pointcut wormhole(<caller context>, <callee context>)
    : cflow(callerSpace(<caller context>))
    && calleeSpace(<callee context<);

     // advices para el wormhole
     around(<caller context>, <callee context>)
     : wormhole(<caller context>, <callee context>) {
       // ... advice body
     }

 }

En la plantilla anterior, los dos primeros pointcuts recolectan los contextos en el llamante y en el
llamado respectivamente. El tercero de ellos construye el wormhole entre los dos espacios, capturando
todos los joint point determinados por el pointcut calleeSpace que se encuentren en el flujo de
ejecución de aquellos joint points capturados por el pointcut callerSpace.

Puede que con un ejemplo nos queden las cosas un poquito más claras. Escribamos un pequeño aspecto
que genere un canal de comunicación entre un sistema iniciador de transacciones y las ejecuciones
de una query:

public aspect SqlTransactionAspect {

      pointcut transactionSystemUsage(TransactionSystem ts)
          : execution(* TransactionSystem.*(..)) && this(ts)

      pointcut queryExecutions(SqlQuery query, String[ ] params)
          : this(query) && args(params)
          && execution(public * SqlQuery.exec*(String [ ]));

      pointcut wormhole(TransactionSystem ts,
                        SqlQuery query, String[ ] params)
          : cflow(transactionSystemUsage(ts))
          && queryExecutions(query, params);

     before(TransactionSystem ts,
           SqlQuery query, String[ ] params) returning
         : wormhole(ts, query, params) {
   // realizar las operaciones deseadas
 }

• El pointcut transactionSystemUsage captura todos los joint point de ejecución en de la clase
  TransactionSystem. Además recolecta el objeto en si en el contexto de ejecución.

• El pointcut queryExecutions() captura todas las llamadas a los métodos exec de la clase SqlQuery
  y recolecta la propia query y los argumentos

• El pointcut wormhole genera un canal de comunicación directo entre el el sistema de transacciones y
  la ejecución de la query, capturando todos los joint points que se produzcan bajo el flujo de ejecución
  de transactionSystemUsage. Además, se captura el contexto de los dos pointcuts constituyentes.

• El advice que actua sobre el pointcut wormhole dispone ahora de toda la información: la query y
  sus parámetros así como el sistema de trasancciones




                                            28
Aspect Oriented Programming


Hilos seguros
        La amplia difusión de los procesadores con múltiples núcleos, el uso de lenguajes especialidados como
        Erlang o Haskell, y la popularidad de numeros libros al respecto, han logrado que los sistemas de
        software alcancen niveles de concurrencia insospechados hasta hace poco tiempo.

        Si embargo, para muchos desarrolladores, incluso gente experimentada,la concurrencia supone un
        auténtico misterio. Implementar un sistema que presente un control de concurrencia es una tarea
        complicada, dado que, en muchas ocasiones, los conceptos se difuminan a lo largo de diferentes
        módulos. Estas circunstancias pueden ocasionar, la construcción de sistemas no demasiado ricos, con
        erros aparentes, caídas del sistema inesperadas, integridad comprometid, deadlocks, . . .

        Por norma general, la implementación de un sistema de concurrencia basado en los patrones
        arquitectónicos y de diseño apropiados suele ocasionar sistemas mucho más fiables que los descritos
        en el párrafo anterior.

        Muchos de los patrones de concurrencia presentan numerosos conceptos trasnversales, por lo que AOP
        puede ayudarnos a simplificar su diseño y posterior implementación.

        En este ejemplo, analizaremos el patrón read-write lock. La implentación clásica de este patrón supone
        la adición de código en todos aquellos métodos que necesiten modificar el estado de un objeto. Los
        siguientes subapartados nos mostarán como podemos realizar una implementación modular de este
        patrón basado en AspectJ.

Implementación tradicional.
        Este patrón utiliza un par de bloqueos (locks): el bloqueo de lectura, y el bloqueo de escritura. Múltiples
        hilos lectores podrán adquirir el bloqueo de lectura siempre y cuando el bloqueo de escritura no haya
        sido adquirido. El otro bloqueo, el de escritura, únicamente podrá ser adquirido siempre y cuando
        ninguno de los hilos restantes haya tomado posesión del bloqueo de escritura.

        La siguiente clase ilustra, mediante una pequeña clase de ejemplo, la solución anterior.


        // package definition . . .

        import java.util.concurrent.locks.ReadWriteLock;
        import java.util.concurrent.locks.ReentrantReadWriteLock;

        /**
        * @author migue
        *
        */
        public abstract class User {
          protected String username;
          protected String login;
          protected int credits;

         public User(int credits) {
           this.credits = credits;
         }

         private ReadWriteLock lock = new ReentrantReadWriteLock();

         public void increaseCredit(int credit) {
          // adquirmos el bloqueo de lectura
          this.lock.writeLock().lock();

           try {




                                                     29
Aspect Oriented Programming


            // realizamos la operación, en este caso,
            // aumentar el crédito del usuario
            this.credits += credit;
          } finally {
            // liberamos el recurso adquirido
            this.lock.writeLock().unlock();
          }
        }

        public void decreaseCredit(int credit) {
         // adquirmos el bloqueo de lectura
         this.lock.writeLock().lock();

          try {
            // realizamos la operación, en este caso,
            // disminuir el crédito del usuario
            this.credits -= credit;
          } finally {
            // liberamos el recurso adquirido
            this.lock.writeLock().unlock();
          }
        }

        public boolean hasCredit() {
          // adquirimos el bloqueo de lectura
          this.lock.readLock().lock();
          boolean hasCredit;
          try {
            hasCredit = this.credits > 0 ? true : false;
          } finally {
            this.lock.readLock().unlock();
          }
          return hasCredit;
        }
        }

       Resulta evidente que la manera anterior de realizar los bloqueos resulta intrusiva, puesto que para cada
       uno de los métodos para los que en los que se desee gestionar la gestión de la concurrencia, tendremos
       que añadir los fragmentos de código vistos en el ejemplo. Cualquier método en el que nos olvidemos
       de añadir el código de gestió de la concurrencia puede ocasionarnos un incorrecto funcionamiento de
       nuestro sistema. Además, debemos asegurarnos que si un método adquire el bloqueo de lectura, sea
       este el que libere, y no el de lectura, y viceversa.

Implementación basada en AspectJ
       Esta alternativa de solución propone a creación de un aspecto que encapule toda la lógica del patrón
       descrito; evitando de este modo la modificación de todas aquellas clases que necesiten hacer uso de
       diho patrón. Puesto que además, el patrón es reutilizable en numerosas situaciones, haremos que el
       aspecto también lo sea.

       La base de la solución, tal y como se indicaba anteriormente, consiste en disponer de un aspecto
       abstracto que implemente toda la lógica del patrón:


       public abstract aspect ReadWriteLockSynchronizationAspect

        perthis(readOperations() || writeOperations())
        {




                                                   30
AOP Chapter 1 Introduction
AOP Chapter 1 Introduction
AOP Chapter 1 Introduction
AOP Chapter 1 Introduction

Mais conteúdo relacionado

Mais procurados

1 conceptos generales de_programacion
1 conceptos generales de_programacion1 conceptos generales de_programacion
1 conceptos generales de_programacionOscar William Coral
 
Unidad3 130504163038-phpapp02 (1)
Unidad3 130504163038-phpapp02 (1)Unidad3 130504163038-phpapp02 (1)
Unidad3 130504163038-phpapp02 (1)Leslie Diaz
 
Proyecto De Tecnica De Programacioin I I
Proyecto De Tecnica De Programacioin  I IProyecto De Tecnica De Programacioin  I I
Proyecto De Tecnica De Programacioin I IAmistadLealtad
 
Cuadro comparativo de herramientas de programacion eclipse, java
Cuadro comparativo de herramientas de programacion eclipse, javaCuadro comparativo de herramientas de programacion eclipse, java
Cuadro comparativo de herramientas de programacion eclipse, javaCCCRiis
 
investigacion topicos avanzados de programacion unidad dos interfaz grafica
investigacion topicos avanzados de programacion unidad dos interfaz graficainvestigacion topicos avanzados de programacion unidad dos interfaz grafica
investigacion topicos avanzados de programacion unidad dos interfaz graficaAnel Sosa
 
Lenguaje de programacion de c++
Lenguaje de programacion de c++Lenguaje de programacion de c++
Lenguaje de programacion de c++zoymar graterol
 
5to ciclo desarrollo de aplicaciones web i
5to ciclo   desarrollo de aplicaciones web i5to ciclo   desarrollo de aplicaciones web i
5to ciclo desarrollo de aplicaciones web iJulio Pari
 
Programación rientada a Aspectos - David Burbano
Programación rientada a Aspectos - David BurbanoProgramación rientada a Aspectos - David Burbano
Programación rientada a Aspectos - David Burbano2008PA2Info3
 
Introducción a la algoritmia
Introducción a la algoritmiaIntroducción a la algoritmia
Introducción a la algoritmiapierre R.
 
Lenguajes de programacion rivas maldonado
Lenguajes de programacion  rivas maldonadoLenguajes de programacion  rivas maldonado
Lenguajes de programacion rivas maldonadoRAUL Velez
 

Mais procurados (20)

1 conceptos generales de_programacion
1 conceptos generales de_programacion1 conceptos generales de_programacion
1 conceptos generales de_programacion
 
Unidad3 130504163038-phpapp02 (1)
Unidad3 130504163038-phpapp02 (1)Unidad3 130504163038-phpapp02 (1)
Unidad3 130504163038-phpapp02 (1)
 
Unidad 3 margie
Unidad 3 margieUnidad 3 margie
Unidad 3 margie
 
Proyecto De Tecnica De Programacioin I I
Proyecto De Tecnica De Programacioin  I IProyecto De Tecnica De Programacioin  I I
Proyecto De Tecnica De Programacioin I I
 
Poa Borrador
Poa BorradorPoa Borrador
Poa Borrador
 
Principios programacion
Principios programacionPrincipios programacion
Principios programacion
 
Programar
ProgramarProgramar
Programar
 
Paradigmas de programación
Paradigmas de programaciónParadigmas de programación
Paradigmas de programación
 
Int a la computacion
Int a la computacionInt a la computacion
Int a la computacion
 
Cuadro comparativo de herramientas de programacion eclipse, java
Cuadro comparativo de herramientas de programacion eclipse, javaCuadro comparativo de herramientas de programacion eclipse, java
Cuadro comparativo de herramientas de programacion eclipse, java
 
Sesion 2
Sesion 2Sesion 2
Sesion 2
 
investigacion topicos avanzados de programacion unidad dos interfaz grafica
investigacion topicos avanzados de programacion unidad dos interfaz graficainvestigacion topicos avanzados de programacion unidad dos interfaz grafica
investigacion topicos avanzados de programacion unidad dos interfaz grafica
 
Errores
ErroresErrores
Errores
 
Lenguaje de programacion de c++
Lenguaje de programacion de c++Lenguaje de programacion de c++
Lenguaje de programacion de c++
 
00463531f7b1b6cf3f000000
00463531f7b1b6cf3f00000000463531f7b1b6cf3f000000
00463531f7b1b6cf3f000000
 
5to ciclo desarrollo de aplicaciones web i
5to ciclo   desarrollo de aplicaciones web i5to ciclo   desarrollo de aplicaciones web i
5to ciclo desarrollo de aplicaciones web i
 
Programacion
Programacion Programacion
Programacion
 
Programación rientada a Aspectos - David Burbano
Programación rientada a Aspectos - David BurbanoProgramación rientada a Aspectos - David Burbano
Programación rientada a Aspectos - David Burbano
 
Introducción a la algoritmia
Introducción a la algoritmiaIntroducción a la algoritmia
Introducción a la algoritmia
 
Lenguajes de programacion rivas maldonado
Lenguajes de programacion  rivas maldonadoLenguajes de programacion  rivas maldonado
Lenguajes de programacion rivas maldonado
 

Semelhante a AOP Chapter 1 Introduction

Programacion Basica
Programacion Basica Programacion Basica
Programacion Basica Yoconditap
 
Presentación de programacion
Presentación  de programacionPresentación  de programacion
Presentación de programacionlajokito
 
Herrera poveda quilachamin_paper
Herrera poveda quilachamin_paperHerrera poveda quilachamin_paper
Herrera poveda quilachamin_paperDarwin Marcelo
 
Programación Orientada a Aspectos - Fernando Córdoba
Programación Orientada a Aspectos - Fernando CórdobaProgramación Orientada a Aspectos - Fernando Córdoba
Programación Orientada a Aspectos - Fernando Córdoba2008PA2Info3
 
Artículo 1 sobre la plataforma ECLIPSE
Artículo 1 sobre la plataforma ECLIPSEArtículo 1 sobre la plataforma ECLIPSE
Artículo 1 sobre la plataforma ECLIPSEtorrubia
 
Programacion Modular
Programacion ModularProgramacion Modular
Programacion Modularguestb97266b9
 
Paradigmas de programacion
Paradigmas de programacionParadigmas de programacion
Paradigmas de programacionyamy matin
 
Herramientas del softaware libre
Herramientas del softaware libre Herramientas del softaware libre
Herramientas del softaware libre nestorlizardo
 
Paradigmasdeprogramacion
ParadigmasdeprogramacionParadigmasdeprogramacion
ParadigmasdeprogramacionVictor Zapata
 
Aplicacion mvc entity_framework_login_membership
Aplicacion mvc entity_framework_login_membershipAplicacion mvc entity_framework_login_membership
Aplicacion mvc entity_framework_login_membershipJose B Flores P
 
Tema1 desarrollo de software basado en componentes
Tema1 desarrollo de software basado en componentesTema1 desarrollo de software basado en componentes
Tema1 desarrollo de software basado en componentesGary Araujo Viscarra
 
Desarrollo de software basado en componentes
Desarrollo de software basado en componentesDesarrollo de software basado en componentes
Desarrollo de software basado en componentesUlises Cruz
 
Diseño de componentes.
Diseño de componentes.Diseño de componentes.
Diseño de componentes.Annel D'Jesús
 
Seminario Spring Roo. Monitorización con Spring Insight
Seminario Spring Roo. Monitorización con Spring InsightSeminario Spring Roo. Monitorización con Spring Insight
Seminario Spring Roo. Monitorización con Spring InsightParadigma Digital
 

Semelhante a AOP Chapter 1 Introduction (20)

Programacion Basica
Programacion Basica Programacion Basica
Programacion Basica
 
Presentación de programacion
Presentación  de programacionPresentación  de programacion
Presentación de programacion
 
Tarea 1
Tarea 1Tarea 1
Tarea 1
 
Herrera poveda quilachamin_paper
Herrera poveda quilachamin_paperHerrera poveda quilachamin_paper
Herrera poveda quilachamin_paper
 
Framework
FrameworkFramework
Framework
 
Programación Orientada a Aspectos - Fernando Córdoba
Programación Orientada a Aspectos - Fernando CórdobaProgramación Orientada a Aspectos - Fernando Córdoba
Programación Orientada a Aspectos - Fernando Córdoba
 
Artículo 1 sobre la plataforma ECLIPSE
Artículo 1 sobre la plataforma ECLIPSEArtículo 1 sobre la plataforma ECLIPSE
Artículo 1 sobre la plataforma ECLIPSE
 
Programacion Modular
Programacion ModularProgramacion Modular
Programacion Modular
 
Programacion Modular
Programacion ModularProgramacion Modular
Programacion Modular
 
Paradigmas de programacion
Paradigmas de programacionParadigmas de programacion
Paradigmas de programacion
 
Power point 3 y 4
Power point 3 y 4Power point 3 y 4
Power point 3 y 4
 
Herramientas del softaware libre
Herramientas del softaware libre Herramientas del softaware libre
Herramientas del softaware libre
 
Paradigmasdeprogramacion
ParadigmasdeprogramacionParadigmasdeprogramacion
Paradigmasdeprogramacion
 
Programacion orientada a objetos Java
Programacion orientada a objetos JavaProgramacion orientada a objetos Java
Programacion orientada a objetos Java
 
Aplicacion mvc entity_framework_login_membership
Aplicacion mvc entity_framework_login_membershipAplicacion mvc entity_framework_login_membership
Aplicacion mvc entity_framework_login_membership
 
Herramientas case
Herramientas caseHerramientas case
Herramientas case
 
Tema1 desarrollo de software basado en componentes
Tema1 desarrollo de software basado en componentesTema1 desarrollo de software basado en componentes
Tema1 desarrollo de software basado en componentes
 
Desarrollo de software basado en componentes
Desarrollo de software basado en componentesDesarrollo de software basado en componentes
Desarrollo de software basado en componentes
 
Diseño de componentes.
Diseño de componentes.Diseño de componentes.
Diseño de componentes.
 
Seminario Spring Roo. Monitorización con Spring Insight
Seminario Spring Roo. Monitorización con Spring InsightSeminario Spring Roo. Monitorización con Spring Insight
Seminario Spring Roo. Monitorización con Spring Insight
 

Mais de Miguel Pastor

Liferay & Big Data Dev Con 2014
Liferay & Big Data Dev Con 2014Liferay & Big Data Dev Con 2014
Liferay & Big Data Dev Con 2014Miguel Pastor
 
Microservices: The OSGi way A different vision on microservices
Microservices: The OSGi way A different vision on microservicesMicroservices: The OSGi way A different vision on microservices
Microservices: The OSGi way A different vision on microservicesMiguel Pastor
 
Liferay and Big Data
Liferay and Big DataLiferay and Big Data
Liferay and Big DataMiguel Pastor
 
Reactive applications and Akka intro used in the Madrid Scala Meetup
Reactive applications and Akka intro used in the Madrid Scala MeetupReactive applications and Akka intro used in the Madrid Scala Meetup
Reactive applications and Akka intro used in the Madrid Scala MeetupMiguel Pastor
 
Reactive applications using Akka
Reactive applications using AkkaReactive applications using Akka
Reactive applications using AkkaMiguel Pastor
 
Liferay Devcon 2013: Our way towards modularity
Liferay Devcon 2013: Our way towards modularityLiferay Devcon 2013: Our way towards modularity
Liferay Devcon 2013: Our way towards modularityMiguel Pastor
 
Liferay Module Framework
Liferay Module FrameworkLiferay Module Framework
Liferay Module FrameworkMiguel Pastor
 
Hadoop, Cloud y Spring
Hadoop, Cloud y Spring Hadoop, Cloud y Spring
Hadoop, Cloud y Spring Miguel Pastor
 
Scala: un vistazo general
Scala: un vistazo generalScala: un vistazo general
Scala: un vistazo generalMiguel Pastor
 
Platform as a Service overview
Platform as a Service overviewPlatform as a Service overview
Platform as a Service overviewMiguel Pastor
 
Software measure-slides
Software measure-slidesSoftware measure-slides
Software measure-slidesMiguel Pastor
 
Groovy and Grails intro
Groovy and Grails introGroovy and Grails intro
Groovy and Grails introMiguel Pastor
 

Mais de Miguel Pastor (18)

Liferay & Big Data Dev Con 2014
Liferay & Big Data Dev Con 2014Liferay & Big Data Dev Con 2014
Liferay & Big Data Dev Con 2014
 
Microservices: The OSGi way A different vision on microservices
Microservices: The OSGi way A different vision on microservicesMicroservices: The OSGi way A different vision on microservices
Microservices: The OSGi way A different vision on microservices
 
Liferay and Big Data
Liferay and Big DataLiferay and Big Data
Liferay and Big Data
 
Reactive applications and Akka intro used in the Madrid Scala Meetup
Reactive applications and Akka intro used in the Madrid Scala MeetupReactive applications and Akka intro used in the Madrid Scala Meetup
Reactive applications and Akka intro used in the Madrid Scala Meetup
 
Reactive applications using Akka
Reactive applications using AkkaReactive applications using Akka
Reactive applications using Akka
 
Liferay Devcon 2013: Our way towards modularity
Liferay Devcon 2013: Our way towards modularityLiferay Devcon 2013: Our way towards modularity
Liferay Devcon 2013: Our way towards modularity
 
Liferay Module Framework
Liferay Module FrameworkLiferay Module Framework
Liferay Module Framework
 
Liferay and Cloud
Liferay and CloudLiferay and Cloud
Liferay and Cloud
 
Jvm fundamentals
Jvm fundamentalsJvm fundamentals
Jvm fundamentals
 
Scala Overview
Scala OverviewScala Overview
Scala Overview
 
Hadoop, Cloud y Spring
Hadoop, Cloud y Spring Hadoop, Cloud y Spring
Hadoop, Cloud y Spring
 
Scala: un vistazo general
Scala: un vistazo generalScala: un vistazo general
Scala: un vistazo general
 
Platform as a Service overview
Platform as a Service overviewPlatform as a Service overview
Platform as a Service overview
 
HadoopDB
HadoopDBHadoopDB
HadoopDB
 
Software measure-slides
Software measure-slidesSoftware measure-slides
Software measure-slides
 
Arquitecturas MMOG
Arquitecturas MMOGArquitecturas MMOG
Arquitecturas MMOG
 
Software Failures
Software FailuresSoftware Failures
Software Failures
 
Groovy and Grails intro
Groovy and Grails introGroovy and Grails intro
Groovy and Grails intro
 

Último

CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE  DE TECNOLOGIA E INFORMATICA PRIMARIACLASE  DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIAWilbisVega
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxLolaBunny11
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveFagnerLisboa3
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan JosephBRAYANJOSEPHPEREZGOM
 
9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudianteAndreaHuertas24
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx241521559
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíassuserf18419
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)GDGSucre
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesFundación YOD YOD
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfsoporteupcology
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricKeyla Dolores Méndez
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITMaricarmen Sánchez Ruiz
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...silviayucra2
 
Herramientas de corte de alta velocidad.pptx
Herramientas de corte de alta velocidad.pptxHerramientas de corte de alta velocidad.pptx
Herramientas de corte de alta velocidad.pptxRogerPrieto3
 

Último (15)

CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE  DE TECNOLOGIA E INFORMATICA PRIMARIACLASE  DE TECNOLOGIA E INFORMATICA PRIMARIA
CLASE DE TECNOLOGIA E INFORMATICA PRIMARIA
 
Presentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptxPresentación guía sencilla en Microsoft Excel.pptx
Presentación guía sencilla en Microsoft Excel.pptx
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
guía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Josephguía de registro de slideshare por Brayan Joseph
guía de registro de slideshare por Brayan Joseph
 
9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante9egb-lengua y Literatura.pdf_texto del estudiante
9egb-lengua y Literatura.pdf_texto del estudiante
 
Proyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptxProyecto integrador. Las TIC en la sociedad S4.pptx
Proyecto integrador. Las TIC en la sociedad S4.pptx
 
Trabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnologíaTrabajo Mas Completo De Excel en clase tecnología
Trabajo Mas Completo De Excel en clase tecnología
 
International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)International Women's Day Sucre 2024 (IWD)
International Women's Day Sucre 2024 (IWD)
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento Protégeles
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdf
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft FabricGlobal Azure Lima 2024 - Integración de Datos con Microsoft Fabric
Global Azure Lima 2024 - Integración de Datos con Microsoft Fabric
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
POWER POINT YUCRAElabore una PRESENTACIÓN CORTA sobre el video película: La C...
 
Herramientas de corte de alta velocidad.pptx
Herramientas de corte de alta velocidad.pptxHerramientas de corte de alta velocidad.pptx
Herramientas de corte de alta velocidad.pptx
 

AOP Chapter 1 Introduction

  • 1. Chapter 1. Aspect Oriented Programming Table of Contents Motivaciones ................................................................................................................ 1 Evolución de las metodologías de programación ................................................................ 3 AOP en el mundo real ................................................................................................... 4 Hype Cycle .......................................................................................................... 4 ¿Dónde se utiliza AOP? ......................................................................................... 6 Introducción a AOP ...................................................................................................... 7 Metodología AOP ................................................................................................. 7 Anatomía de un lenguaje orientado a aspectos ........................................................... 8 Beneficios de la metodología AOP ........................................................................... 9 Verdades y mentiras sobre AOP ............................................................................ 10 Visión general de AspectJ ............................................................................................. 11 Introducción a AspectJ ......................................................................................... 11 Modelo de Joint Point ......................................................................................... 11 Crosscutting dinámico .......................................................................................... 18 Aspectos ............................................................................................................ 24 Resumen ............................................................................................................ 25 Ejemplos reales ................................................................................................... 26 Bibliografía ................................................................................................................ 33 Motivaciones Antes de profundizar en la temática propia de la orientación a aspectos y sus aplicaciones en el mundo real, sería conveniente describir las motivaciones principales que han ocasionado la escritura de este capítulo de la memoria. La primera de ellas ha sido la intención de introducir al lector en algunas de las técnicas de desarrollo avanzadas utilizadas en la actualidad por los equipos de desarrollo de software más vanguardistas. La segunda está relacionada con el desarrollo de nuevas herramientas de programación y, por ende, con la herramienta desarrollada como ejemplo de este proyecto: R-Eclipse. Si el lector desconoce muchos de los términos definidos en esta sección no se preocupe, a lo largo del capítulo comprenderá la terminología aquí utilizada. En los últimos años han surgido muchos lenguajes similares a Java que se ejecutan sobre la propia máquina virtual de este último (JVM), lo cual es un indicador bastante fiable del futuro del desarrollo de aplicaciones sobre la plataforma Java.1Sin embargo, Eclipse y su solución JDT, no ofrecen soporte para la integración de estos nuevos lenguajes en su modelo Java subyacente. Por ejemplo, no existe un modo de incluir jerarquías de tipos,jerarquías de llamadas, etc. 1 R Eclipse no ha utilizado el enfoque descrito en esta sección por dos motivos principalmente; el primero de ellos es que R no es un lenguaje similar a Java ni corre bajo su máquina virtual. El segundo de ellos consiste en que el framework base de desarrollo, DLTK, no utiliza la arquitectura descrita en estas líneas. 1
  • 2. Aspect Oriented Programming Figure 1.1. Herramientas para nuevos lenguajes Algunos de los problemas que se encuentran los ingenieros de software cuando intentan construir herramientas para algunos de los lenguajes descritos anteriormente son: • Necesidad de acoplarse al modelo ofrecido por JDT. No se puede. • Necesidad de acoplarse al motor de indexación de código fuente. No se puede. • Necesidad de acoplarse al parser de JDT. No se puede. Una aproximación utilizada por muchos entornos de desarrollo de lenguajes actuales como pueden ser Scala o Groovy es la utilización del servicio de tejido de JDT. Las características principales son: • Utiliza AspectJ añadiendo puntos de unión al modelo JDT • Se encapsula en puntos de extensión de Eclipse, haciéndolo extensible a terceras partes. • Utiliza un proyecto de Eclipse conocido como Equinox Aspects que soporta el proceso de tejido en tiempo de carga en un entorno OSGI. El siguiente gráfico ilustra como funciona el proceso anterior: 2
  • 3. Aspect Oriented Programming Figure 1.2. Proceso de acoplamiento al JDT A lo largo de las siguentes secciones se introducirá la terminología AOP así como la definición de sus elementos más relevantes. Evolución de las metodologías de programación La ingeniería del software ha recorrido un largo camino desde sus inicios: desde el código máquina hasta la orientación a objetos pasando por los lenguajes procedimentales. Analizando de manera somera la evolución de las metodologías de programación observamos cómo el modelo procedimental introdujo la abstracción funcional y la orientación a objetos los conceptos de composición, reutilización y encapsulación. Este último paradigma ha sido, posiblemente, una de las mayores contribuciones al mundo del software durante toda su historia y,en la actualidad, es el paradigma de programación utilizado en la mayor parte de los grandes desarrollos de software. Entre todas las ventajas del paradigma de orientación a objetos, en el párrafo anterior se destacaba, no al azar, la reutilización y la encapsulación pero . . . ¿siempre es posible ubicar en el mismo lugar todas las tareas relacionadas con una misma función?, ¿en alguna ocasión has visto un fragmento de código que no encaja en ninguna clase en particular?. Imaginemos un sistema en el que determinadas operaciones necesitan llevar a cabo una gestión de transacciones. Resultaría sumamente complicado,por no decir imposible, modularizar todos los conceptos necesarios en un sistema transaccional: inicialización, comunicación con el manager de transacciones, rollbacks, . . . Esto es debido a que todos los métodos de un objeto que requieren un control de transacciones necesitan ser conscientes que la operación a realizar se ejecuta bajo un control transaccional, para comportarse de manera acorde al funcionamiento requerido. Resumiendo, el código encargado de la gestión de transacciones estaría ubicado en cada uno de los objetos que lo necesite. La solución comunmente adoptada a este problema es copiar y pegar el código en todas aquellas partes en las que es necesario, resultando evidente, que dicha solución no permite disponer de una buena modularización y dificulta las labores de mantenimiento y evolución del código. Este 3
  • 4. Aspect Oriented Programming fenómeno es conocido como scattering , puesto que el código relacionado con un mismo asunto se encuentra repartido a lo largo de todo el sistema. Sumemos, además, que los módulos que contienen código relativo a muchos asuntos diferentes tienden a ser, en general, menos reutilizables. El fenómeno en el que diferentes asuntos son entremezclados en el código se conoce como tangling . La problemática introducida en los párrafos anteriores, tangling y scattering , afecta al diseño y desarrollo de software de muchas y diferentes maneras. Veamos alguna de las principales: • Trazabilidad reducida. La implementación de diferentes conceptos en un mismo lugar dificulta el proceso de establecimiento de una relación entre los requisitos y su implementación y viceversa. Así por ejemplo, para completar la trazabilidad del requerimiento de autenticación podríamos llegar a examinar todos los módulos del sistema. • Baja producitividad. Varios conceptos no relacionados que han sido implementados en un mismo lugar ocasiona que la atención se disperse a lo largo de todos ellos. La falta de un objetivo concreto provoca que los desarrolladores se vean obligados a manejar diferentes conceptos no relacionados con el objetivo principal. En muchas ocasiones,la construcción de un módulo implicará la participación de diversos desarrolladores, con diferentes perfiles, o que el desarrollador tenga conocimiento en todos los ámbitos que se están incluyendo en el nuevo módulo. • Escasa reutilización del código. Los conceptos implementados en un módulo podrían ser requeridos por otros módulos con funcionalidades similares • Baja calidad. El code tangling provoca que el código sea más difícil de leer, de ubicar los potenciales problemas y de hacer revisiones del mismo. Por ejemplo, la revisión de código de un módulo en el que se implementan diversos conceptos requerirá la presencia de expertos en cada uno de ellos. A menudo muchos de estos expertos no estarán disponibles de manera simultánea, y el resto no prestará demasiada atención en los temas que se encuentren fuera de su área de conocimiento. • Dificultad para llevar a cabo evoluciones. La falta de recursos o una visión incompleta derivan en un diseño que maneja únicamente los conceptos actuales. Cuando aparezcan nuevos requerimientos,a menudo, nos veremos obligados a reimplementar. Dado que la implementación no se encuentra modularizada,la inclusión de un nuevo requerimiento podría obligar a realizar cambios en todos los módulos. Los problemas descritos en los puntos anteriores han servido como impulso en la búsqueda de nuevos y mejores enfoques en la arquitectura, diseño e implementación. AOP ofrece una solución a todos los problemas anteriores. AOP en el mundo real ¿Qué lugar ocupa la orientación a aspectos en el mundo real? ¿Deberíamos prestarle atención o ignorarlo por completo? ¿Cuáles son los beneficios aportados? ¿y los posibles riesgos de adopción de esta tecnología?. Estas y otras preguntas serán respondidas, desde un punto de vista práctico, en los siguientes subapartados de esta sección. Hype Cycle Hype Cycle es una representación gráfica del grado de madurez, adopción y aplicación en el mundo real de una tecnología determinada. Es importante comprender bien el gráfico anterior, y la posición de la tecnología que se está considerando; en este caso, AOP, puesto que se dispondrá de una visión mucho más ajustada de los riesgos y beneficios a los que nos estamos exponiendo. 4
  • 5. Aspect Oriented Programming Figure 1.3. Diagrama de componentes de R-Eclipse La interpretación de la curva Hype Cicle implica cinco fases diferentes las cuales analizaremos a continuación, relacionándolas, evidentemente con AOP. Activación de la tecnología Este es el momento en el que la tecnología aparece con la intención/promesa de solucionar un conjunto determinado de problemas. Podría ser el anuncio de un nuevo producto o la liberación de una nueva versión de un producto ya existente. En el caso de AOP, este proceso de activación se produjo en 2002 con el lanzamiento de AspectJ 1.0, seguido de una liberación mucho más importante (AspectJ 1.1) en el año 2003. Mucha gente se dio cuenta del potencial de AspectJ, especialmente su utilización en aplicaciones empresariales. Expectativas irreales ("peak") Durante esta fase la tecnlogía se hace muy popular. Todo el mundo quiere conocerla y tiene una opinión sobre ella aunque muy poca gente la utiliza en aplicaciones reales. Durante el año 2004 la mayoría de desarrolladores que trabajaban en Aspectj y AspectJ Development Tools (AJDT) eran integrantes de IBM. Esta inversión por parte de IBM proporcionó una base sólida a AspectJ. La ausencia de una adopción masiva hizo que el uso de la tecnología se conviertiese en una auténtica aventura. Afortunadamente para AspectJ el pico en esta fase no fue demasiado eleveado, sobre todo debido al manejo de las expectativas que realizaron sus principales evangelistas. Esta gestión provocó un pico más bajo en el hype cycle, lo que supuso una caída mucho menor en la siguiente fase. Desilusión Esta es la fase de ciclo Hype en la que la tecnología comienza a perder toda la atención que se le había prestado hasta el momento. Mientras que los equipos que la adoptaron desde sus inicios continuan utilizándola con el objetivo de obtener una ventaja competitiva, muchos otros comienzan a observarla con cierto escepticismo. Nuevas tecnologías aparecen en escena aportando soluciones diferentes al mismo problema. Resulta 5
  • 6. Aspect Oriented Programming interesante destacar que muchos de estos nuevos competidores están en la fase de "expectativas irreales". AOP atravesó esta fase durante 2006 aproximadamente. Enterprise Java Beans ofrecía una seria competencia, permitiendo implementar funcionalidades transversales como seguridad o transaccionalidad de una manera modular. Pero EJB no era el único competidor, y tampoco el más importante. La aparición de lenguajes dinámicos como Groovy o Ruby y sus frameworks asociados, Grails y Rails, supuso una dura competencia para AOP. El modelo de metaprogramación del que disponen estas tecnologías facilitaba una nueva solución para realizar la modularización de funciones transversales. Viendo la luz Numerosos factores intervienen en el desarrollo de esta fase: maduración de la tecnología, cambios en la misma para acercarse a la realidad, búsqueda de un contexto de uso en el que realmente se cause impacto o la "desilusión" con otras alternativas, que en su momento fueron competidores, son algunas de ellas. En el caso de AOP, el comienzo de esta fase se produjo cuando algunos de los líderes del proyecto abandonaron IBM para fichar por SpringSource:Adrian Colyer,Andy Clement, Andrew Eisinberg, . . ., conviertiendo a AspectJ en un proyecto más del portfolio de Spring. Analicemos los factores enumerados anteriormente: • Acercamiento a la realidad:La introducción de anotaciones en Java 5, los cambios en la sintáxis o la supresión del proceso de weaving si se utiliza conjuntamente con Spring fueron algunos de los cambios realizados. La mejora en las herramientas de desarrollo fue otra de las respuestas a las necesidades reales de los usuarios. • Contexto de utilización: la influencia de Spring: En sus inicios AspectJ carecía de un contexto de utilización definido (C nació en el ámbito de los sistemas operativos, C++ en el contexto de interfaz de usuario, etc). Ha sido Spring la que le ha proporcionado a AspectJ un contexto de uso bien definido: la aplicaciones empresariales. • Desilusión con los competidores: Anteriormente indicamos que EJB permitía modularizar los conceptos transversales de un sistema. Los desarrolladores se dieron cuenta de que la solución ofrecida era demasiado pesada en la mayoría de las ocasiones. La versión 3 de EJB introdujo interceptores, un concepto similar a los advices de AspectJ, aunque carecían de un modelo de unión. Los lenguajes dinámicos ofrecen una gran alternativa a AspectJ aunque son relativamente nuevos. Tendremos que esperar el paso del tiempo y el uso en grandes aplicaciones empresariales para determinar la evolución de los mismos, y ver cómo continúa evolucionando AspectJ. Plena productividad Es la última fase definida en el ciclo Hype. En esta situación la tecnología está ampliamente difundida y se utiliza en las solución de problemas para los que ofrece una gran respuesta. Será en esta fase cuando se produzca una aceptación mavisa de la tecnología. En la actualidad,Java o C , se encuentran en esta fase. AOP y AspectJ deberán alcanzar este nivel con el paso del tiempo. ¿Dónde se utiliza AOP? A continuación se analizarán algunos de los principales ámbitos de aplicación de AOP Aplicaciones empresariales Gestión de transacciones, seguridad, auditoría, monitorización, gestión de la concurrencia, manejo de errores y un largo ecétera son funcionalidades transversales en la mayoría de aplicaciones empresariales. 6
  • 7. Aspect Oriented Programming Aquellas aplicaciones que usen Spring como base de su arquitectura ya estarán utilizando algunos de los aspectos que vienen facilitados por el framework. Gracias a las anotaciones, concretamente @Aspect, la construcción de aspectos se ha convertido en una tarea habitual. Web y servidores de aplicaciones Aplicación de políticas, FFDC, recolección de contextos,trazabilidad o monitorización son algunas de las funcionalidades basadas en AOP que podemos encontrar en los servidores de aplicaciones. Spring Source DM Server y TC Server son un claro ejemplo de estas funcionalidades. Frameworks Gestión de transacciones y seguridad son habitualmente implementadas mediante aspectos. Asimismo, otras utilizaciones de los aspectos podría ser la inyección de dependencias en objetos de dominio. Para obtener un amplio abanico de posibilidades de uso de los aspectos, el lector podría visitar los proyectos de Spring Roo o Apache Magma. Herramientas de monitorización El uso de aspectos facilita también la construcción de herramientas de monitorización. Muchas herramientas utilizan AspectJ como tecnología subyacente: Glassbox,Perf4J,Contract4J,JXInsight o MaintainJ son algunos de los ejemplos. Compiladores e integración de IDE's El mismo equipo de AspectJ utiliza la propia tecnología para extender el compilador de JDT de manera que sea capaz de sopotar las nuevas construcciones. AJDT utilizan un proceso de weaving a través de una implementación basada en OSGI ofrecida por el proyecto Equinox. Scala IDE en Eclipse utiliza un enfoque similar para la construcción del entorno de desarrollo.2 Introducción a AOP AOP se construye sobre metodologías existentes como OOP o programación funcional, mejorándolas con las construcciones necesarias que permiten modularizar correctamente los conceptos transversales. Por ejemplo, si se trabaja con OOP, el núcleo de nuestro sistema será implementado mediante la utilización de clases. Los aspectos serán los encargados de representar las funcionalidades transversales y determinar cómo todos los diferentes módulos deberán ser tejidos para construir el sistema final. Metodología AOP Desarrollar un sistema utilizando AOP es similar a un desarrollo basado en otras metodologías: determinar los requerimientos, implementarlos y construir el sistema final mediante la combinación de los mismos. La comunidad AOP define tres pasos: 1. Descomposición en aspectos En este paso se indentificarán los diferentes concerns , tanto los transversales como los que componen el núcleo. Por ejemplo, en una capa de negocio encargada de calcular el IVA total de los productos los aspectos pertenecientes al núcleo sería el cálculo del IVA en sí, mientras que elementos como la transaccionalidad, registro de actividad,seguridad en hilos, manejo de cachés, . . . serían conceptos de un espectro mucho más amplio, que serán necesitados en otros muchos módulos del sistema, y por tanto, se categorizan como conceptos transversales 2. Implementación de "concerns" En este punto tendrá que realizarse la implementación de los diferentes requerimientos de manera independiente . Siguiendo con el ejemplo anterior, un grupo 2 Ver la sección inicial de este capítulo 7
  • 8. Aspect Oriented Programming sería el encargado de realizar la implementación del módulo de lógica de negocio encargado de calcular el IVA, otro grupo llevaría a cabo la gestión del logging, un tercer grupo sería el encargado de asegurarse que las operaciones fuesen thread safe , y así sucesivamente. 3. Recomposición de aspectos . En este paso se deben definir las reglas de composición mediante la creación de módulos o aspectos . Este proceso, conocido como weaving , utiliza esta información para construir el sistema final. La principal aportación de AOP es la independencia de los "concerns" en el momento de su implementación. El modo en que se realiza la implementación permite una completa trazabilidad entre los requerimientos y su implementación, por lo que el sistema final será más fácil de comprender, implementar o adaptar ante futuros cambios Anatomía de un lenguaje orientado a aspectos La orientación a aspectos es simplemente una metodología por lo que será necesario definir el lenguaje y ofrecer un conjunto de herramientas para trabajar con la misma. Al igual que otra metodología de programación, una implementación concreta de AOP constará de dos partes: • Especificación del lenguaje encargado de describir las construcciones y sintaxis que serán utilizadas en la construcción y el tejido de todos los "concerns", tanto los pertenecientes al núcleo como los transversales. • La implementación del lenguaje es la encargada de verificar la adherencia del código a la especificación del lenguaje y de trasladar el código a un ejecutable capaz de ser comprendido por una máquina. Esta tarea,habitualmente,es realizada por un compilador o un intérprete. Especificación del lenguaje AOP Cualquier implementación de la metodología AOP requiere la definición de dos lenguajes: el primero de ellos permitirá realizar la implementación de los requisitos individuales mientras que gracias al segundo podremos definir las reglas que "tejen" el conjunto de módulos independientes. • Implementación de concerns .Al igual que en otras metodologías, los requisitos se implementan en módulos que contienen los datos y el comportamiento necesario para ofrecer sus servicios. Imaginemos por ejemplo que estamos construyendo el núcleo del concern de seguridad; dicho núcleo mantendrá un manager de control de accesos y una colección de elementos ( voters ). Habitualmente,tanto los concerns transversales como los del núcleo se implementan mediante la utilización de lenguajes estándar como pueden ser C++ o Java. • Especificación de reglas de "tejido". Las reglas de tejido especifican cómo debemos integrar los diferentes concerns que hemos implementado para componer el sistema final. El lenguaje utilizado para definir estas reglas puede ser una evolución del lenguaje natural o algo completamente diferente. Así por ejemplo, podríamos ofrecer una implementación de la metodología AOP en la que Java es el lenguaje base y la definición de reglas de tejido se realiza mediante un DSL implementado en Groovy . Implementación de AOP La implementación del lenguaje debe llevar a cabo dos acciones:combinar los aspectos individuales mediante las reglas de tejido,para, posteriormente, convertir la información resultante en código ejecutable. El primero de los dos pasos anteriores es conocido como weaving, y el procesador encargado de realizar dicha tarea es el weaver. • Proceso de weaving . Tal y como argumentaba la introducción de este punto, el proceso de weaving es el encargado de componer el sistema final mediante la composición de los diferentes concerns siguiendo las pautas establecidas en las reglas de tejido . Estas reglas son definidas en aspectos 8
  • 9. Aspect Oriented Programming independientes del núcleo del sistema por lo que con unas nuevas reglas de "tejido" podríamos construir un sistema final completamente diferente. • Procesador (Weaver) El procesador encargado de llevar a cabo el proceso de weaving descrito en el punto anterior es comunmente conocido como weaver Una posible implementación sería utilizar una transformación código a código (un compilador). De ese modo, el compilador de aop "tejería" los aspectos junto al resto de clases generando un nuevo código ya "tejido". Una vez finalizado este proceso, el código generado anteriormente serviría como entrada para el compilador de lenguaje base el cual sería el encargado de generar el ejecutable. Utilizando el enfoque anterior, una aproximación basada en C++ convertiría todos los archivos individuales (aspectos y clases) en código C++ tejido(weaving). El siguiente diagrama ilustra la aproximación descrita en el párrafo anterior: Figure 1.4. Proceso de generación del sistema final Beneficios de la metodología AOP La mayoría de las críticas sobre AOP destacan que en muchas ocasiones es demasiado complejo. Evidentemente, es necesario un poco de tiempo y paciencia para conseguir ser un experto. Sin embargo, el motivo principal de su complejidad es que se trata de una tecnología relativamente nueva. Algunos de los beneficios más detacables de esta metodología son: • Responsabilidades claramente diferenciadas . Cada módulo es el responsable de su funcionalidad principal; dejando de lado los conceptos transversales. Así por ejemplo, un módulo cuyo principal cometido es implementar la lógica de acceso a datos de un sistema de ventas por internet, no tendrá que preocuparse de realizar pooling sobre la base de datos o de la transaccionalidad. Gracias a esta clara asignación de responsabilidades se consigue una alta trazabilidad entre los requisitos y su correspondiente implementación. • Incremento de la modularidad . Utilizando AOP se consigue manejar cada uno de los conceptos de manera independiente con un acoplamiento mínimo. Incluso aunque estén presentes conceptos transversales que afecten al sistema completo, la implementación es modular. • Retraso en las decisiones de diseño .Cuando se arquitecta un nuevo sistema siempre aparece el siguiente dilema: ¿se debe realizar un diseño sumamente complejo y detallado que intente abarcar todas las funcionalidades,incluso las futuras? o, por el contrario, ¿debe arquitectarse una solución que se corresponda con la situación actual?. Gracias a AOP, el arquitecto de la solución, puede retrasar la toma de determinadas decisiones de diseño dado que los futuros requerimientos se implementarán en aspectos independientes. Dando un paso más adelante, AOP conforma un gran equipo junto con una metodología ágil como puede ser 9
  • 10. Aspect Oriented Programming XP (siglas en inglés de Programación Extrema) siguiendo la práctica del principio YAGNI (siglas en inglés de No lo vas a necesitar ) . De este modo, podemos seguir el principio anterior, dando vida únicamente a las funcionalidades requeridas e implementando futuros requerimientos sin la necesidad de grandes modificaciones en el sistema. • Sencillez en las mejoras . AOP permite añadir una nueva funcionalidad sin más que desarrollar un nuevo aspecto (el cual no afecta al núcleo del sistema). Gracias a ello, el tiempo de respuesta ante nuevos requerimientos disminuye notablemente. • Incremento en la reutilización del código .Puesto que AOP implementa cada aspecto en un módulo independiente, cada uno de ellos es independiente del resto. En general, cada uno de ellos no suelen tener conocimiento del resto de elementos que conforman el sistema final. Realmente, el único elemento consciente del acoplamiento entre los diferentes módulos son las reglas de tejido , de manera que, si cambiamos éstas, podemos componer un sistema final completamente diferente. • Reducción de costes y accesos al mercado más rápidos .Las características descritas en los puntos anteriores generan sistemas más rápidos, tanto en su desarrollo como en su implantación . Eliminando la necesidad de modificar múltiples módulos para la implementación de un nuevo concepto transversal, AOP provoca que dicha implementación sea más barata. Asimismo, permitiendo que los desarrolladores estén centrados en su especialidad logramos que el coste del desarrollo disminuya. Verdades y mentiras sobre AOP En los últimos años AOP ha sufrido un gran crecimiento aunque,en algunas ocasiones, todavía se percibe demasiado complicado, tanto en su implementación como en su proceso de aprendizaje. A continuación veremos algunas hipótesis y los motivos por los que las mismas son consideradas ciertas o falsas: • AOP no soluciona nuevos problemas . Esta afirmación es completamente cierta. La orientación a aspectos no ofrece solución a problemas irresolubles sino que aporta soluciones más sencillas y elegantes a los problemas actuales. Al fin y al cabo, no hay nada que no podamos implementar con código máquina. • Flujos complicados de seguir . De nuevo esta afirmación es cierta. En muchas ocasiones, en función de la complejidad del sistema que estemos construyendo, el orden en el que se ejecutan las instrucciones puede resultar complicado de seguir. La afirmación anterior también es cierta para otras metodologías ajenas a AOP. En OOP, el uso del polimorfismo hace que analizar el flujo de ejecución de un programa no sea una tarea sencilla. Incluso en lenguajes procedimientales, como podría ser C, el uso de punteros a funciones dificulta las tareas de seguimiento del programa. • AOP promueve malos diseños . En esta ocasión la afirmación es falsa. Una aproximación orientada a aspectos no es la solución para un mal diseño sino que simplemente facilita nuevos modos de resolución de problemas en aquellas áreas en las que lenguajes procedimientales u orientados a objetos presentan carencias. • Los interfaces de las metodologías OOP son suficientes . De nuevo en esta ocasión, la afirmación anterior es falsa. La técnica descrita propone utilizar un interfaz e ir intercambiando las implementaciones subyancentes (nótese que esto no implica cambios en el API). Puede parecer a simple vista que esta solución es satisfactoria, pero dista mucho de ser así, puesto que necesitamos invocar al código en todos aquellos lugares en los que corresponda. Esta técnica sirve de gran ayuda (tanto en OOP como AOP), pero en ningún momento los interfaces son una alternativa a la orientación a aspectos. • AOP supone una ruptura de la encapsulación . Esto afirmación es cierta aunque con ciertos matices puesto que dicha ruptura se realiza de una manera controlada y sistemática. Las clases en OOP 10
  • 11. Aspect Oriented Programming encapsulan todo el comportamiento, mientras que AOP elimina estos niveles de control de las mismas. • AOP reemplazará a OOP . Falso. Los conceptos principales seguirán siendo implementados en OOP ( o puede que en un lenguaje procedimantal como puede ser C). AOP añade un nuevo conjunto de conceptos adicionales a la metodología orientada a objetos. Efectivamente, AOP cambiará el modo en el que se utilizan las metodologías actuales para la implementación de conceptos transversales. Visión general de AspectJ AspectJ es una extensión orientada a aspectos de propósito general al lenguaje Java. Puesto que es una extensión del lenguaje Java, cualquier programa escrito en dicho lenguaje es un programa AspectJ válido. Un compilador AspectJ genera archivos .class de acuerdo a la especificación del bytecode de Java de manera que cualquier implementación de la máquina virtual sea capaz de ejecutar dichos archivos. El lenguaje AspectJ , de acuerdo a los conceptos descritos en el apartado anterior, consta de dos partes: la especificación del lenguaje que define los conceptos principales implementados mediante clases Java, y las extensiones AOP que permiten realizar el tejido de los conceptos transversales. La implementación del lenguaje facilita herramientas como compiladores, depuradores e integración con la mayoría de IDE´s modernos. Los siguientes apartados servirán de introducción a AspectJ y algunos conceptos avanzados gracias a los cuales se podrá comenzar a escribir programas simples. Introducción a AspectJ El compilador de AspectJ es el encargado de utilizar los módulos que contienen las definiciones de las reglas de tejido para añadir nuevo comportamiento a los módulos que implementan las funcionalidades principales. El proceso anterior no realiza ninguna modificación sobre el código fuente del núcleo dado que el proceso de tejido se realiza sobre el bytecode generado por el compilador. Modelo de Joint Point El modelo de joint point (no vamos a traducir el término) está compuesto de dos partes claramente diferenciadas: los "join point", que no son más que puntos en la ejecución de un programa, y los "pointcuts", un mecanismo de selección de los puntos anteriores. Imaginemos por un momento que nos encontramos desarrollando un sistema que necesita gestión de la seguridad, algo muy común en el mundo en el que nos movemos, y, que, debido a la naturaleza transversal del mismo, elegimos AOP como enfoque principal de nuestra solución. ¿Cuáles son los pasos que deberíamos seguir? 1. Identificar los puntos del sistema que necesitan ser protegidos, comprobando, antes de realizar el acceso, que el usuario está autenticado y tiene los privilegios necesarios para hacerlo. En resumen, estamos identificando los "joint point" que requieren ser securizados. 2. Construiremos un pointcut (o varios, todos los que sean necesarios), que permita la selección de los "joint point" descritos en el punto anterior. 3. Construiremos un aspecto que encapsule toda la lógica de seguridad requerida. Los conceptos anteriores son sumamente importantes dado que componen la base de AOP. Los siguientes subapartados profundizarán en cada uno de ellos. 11
  • 12. Aspect Oriented Programming Joint Point Como ya se definió anteriormente, un join point es un punto de ejecución en un sistema. Así por ejemplo, el acceso al campo de una clase, la ejecución de una función o una sentencia for son ejemplos de join points. AspectJ solamente expone un subconjunto de todos los posibles joint points, limitando de este modo, el acceso a las construcciones más estables. Pointcuts Es un artefacto que nos permite seleccionar joint points y recuperar su contexto.Veamos algunas de las características principales: Selección de joint points Los pointcut especifican un criterio de selección. Utilizaremos tipos, campos, métodos, anotaciones, etc para generar dichas definiciones. También podremos establecer condiciones en tiempo de ejecución que tendrán que cumplirse en el joint point seleccionado. Determinación del contexto Los joint point disponen de información en tiempo de ejecución. Determinados pointcuts pueden recolectar dicha información y pasársela al advice. Por ejemplo, la llamada a un método de un objeto tendrá disponible el propio objeto que realiza la llamada y los argumentos que se están pasando. Utilización de signaturas En Java, todos los elementos que componente un programa tienen una signatura. La utilización de patrones para dichas signaturas permiten a los pointcuts especificar las reglas que permiten seleccionar los joint point deseados. Categorías de joint points A continuación se verá un conjunto de categorías de joints points expuestas por AspectJ. A pesar de ser un número considerable de categorías, no se han incluido todas, sino aquellas que se utilizan con mayor frecuencia. Si el lector desea realizar una lectura más profunda aquí podrá encontrar todo lo que necesita: AspectJ Programming Guide [http://www.eclipse.org/aspectj/docs.php] Table 1.1. Categorías de joint points expuestas por AspectJ (resumen) Categoría Joint Point Expuesto Código que representa Método Execution Cuerpo del método Método Call Invocación del método Constructor Execution Ejecución de la lógica de creación de un objeto Constructor Call Invocación de la lógica de creación de un objeto Acceso a un campo Read Lectura de un objeto o el campo de una clase Acceso a un campo Write Escritura de un objeto o el campo de una clase Proceso de excepciones Handler Bloque catch para manejar una excepción Inicialización Class init Proceso de carga de una clase (class loading) Inicialización Object init Inicialización de un objeto en un constructor Inicialización Object pre-init Pre-inicialización de un objeto en un constructor Advice Execution Ejecución de un advice 12
  • 13. Aspect Oriented Programming Conceptos básicos A continuación se analizarán los elementos básicos que se deben conocer para definir un pointcut. Pointcuts anónimos o con nombre Se permite la declaración de pointcuts de cualquiera de los dos tipos. Los primeros son similares a las clases anónimas, y por tanto se definen en el lugar en el que se van a utilizar. En el caso de los segundos, podremos referenciarlos desde múltiples lugares, permitiendo de este modo su reutilización. Operadores AspectJ proporciona el operador unario de negación (!) y dos operadores binarios: && y ||, gracias a los cuales se permite construir reglas de matching complejas mediante la combinación de pointcuts más sencillos. Tanto la semántica como la precedencia es la misma que en el lenguaje Java. Así por ejemplo,en el caso del operador binario &&, se seleccionarán aquellos joint points que concuerden con los dos pointcuts que actúan como operandos. Signaturas: sintaxis y ejemplos Las signaturas son la base de la definición de los pointcuts. El lenguaje debe facilitar una manera sencilla que permita definir criterios de selección sobre los diferentes aspectos transversales que estamos implementando. En el caso de AspectJ, se utilizan expresiones regulares (wildcards) en combinación a las signaturas. Los siguientes wildcards son soportados: • * especifica cualquier número de caracteres, exceptuando el punto (.). En la signatura de un tipo, denota una parte de un tipo o de un paquete. En otros patrones denota una parte del nombre (por ejemplo en métodos o campos) • .. determina cualquier número de caractéres, incluyendo en este caso cualquier número de puntos (.). En la signatura de un tipo representa cualquier paquete o subpaquete. En la signatura de un método representa cualquier número de argumentos. • + denota cualquier subtipo de un tipo determinado. A lo largo de los siguientes subapartados veremos, a través de una serie de ejemplos, los diferentes patrones de signaturas ofrecidos por AspectJ que podemos utilizar para seleccionar dierentes joint points Signaturas de tipos Table 1.2. Ejemplos de signaturas de tipos Patrón de la Descripción Ejemplos de tipos concordantes signatura AstVisitor El tipo AstVisitor Sólo el tipo AstVisitor concuerda (ni tipos base ni derivados) *AstVisitor Cualquier tipo cuyo nombre termine en Por ejemplo, HighlightingAstVisitor o AstVisitor SemanticAstVisitor concuerdan con el patrón java.*.Date El tipo Date en cualquier subpaquete java.util.Date o java.sql.Date son directo del paquete java ejemplos de tipos concordantes javax..* Cualquier tipo en el paquete javax y en Cualquier tipo en el paquete sus subpaquetes (tanto directos como javax.security así como cualquiera indirectos) de sus subpaquetes indirectos como javax.security.auth.login 13
  • 14. Aspect Oriented Programming Patrón de la Descripción Ejemplos de tipos concordantes signatura javax..*Model Todos los tipos en el paquete javax TableModel, TreeModel y sus (subpaquetes directos e indirectos) subtipos como DefaultTreeModel o cuyo nombre termine en Model, y todos DefaultTableModel. los subtipos de estos. Singaturas de tipos: anotaciones Table 1.3. Ejemplos de signaturas de tipos: anotaciones Patrón de la Descripción Ejemplos de tipos concorndantes signatura @Secured User El tipo User anotado con la anotación @Secured class User{. . .} Secured @Entity * Cualquier tipo anotado con la anotación @Entity class Section {. . .},@Entity Entity class Report {. . .} @Transactional* El tipo Manager y cualquiera de sus @TransactionalDefault class Manager+ clases derivadas que estén anotados con Manager{},@TransactionalOracle una anotación cuyo nombre comienze class OracleManager extends por Transactional Manager{} Signaturas de tipos: generics Table 1.4. Ejemplos de signaturas de tipos: generics Patrón de la Descripción Ejemplos de tipos concordantes signatura Map El tipo Map cuyo primer argumento En este caso únicamente concordará el <Integer,String> genérico está fijado a Integer y el tipo Map<Integer,String> segundo a String *<User> Cualquier tipo genérico cuyo único Collection<User>,List<User>, . . . argumento genérico sea de tipo User Collection<? El tipo Collection con un parámetro de Collection<User>, extends User> tipo User o derivado Collection<DomainUser>, . . . Collection<? El tipo Collection, cuyo parámetro será Collection<Serializable>, super User> uno de los tipos base de User Collection<BaseUser>, asumiendo que, User extiende o implementa, directa o indirectamente, Serializable y BaseUser Combinando pointcuts: operadores Table 1.5. Signaturas de tipo: operadores Patrón de la Descripción Ejemplos de tipos concordantes signatura !Collection Cualquier tipo excepto Collection User,Model, List (aunque sea subclase de Collection) Set || Map Los tipos Set o Map Los tipos Set y Map únicamente !@Transactional Cualquier tipo que se encuentre anotado class NonTransactionalManager{} por por la anotación Transactional @Serializable Cualquier tipo que se encuentre anotado @Serializable @Encrypted class @Encrypted * por las dos anotaciones UserCredentials{} 14
  • 15. Aspect Oriented Programming Patrón de la Descripción Ejemplos de tipos concordantes signatura (@Serializable || Cualquier tipo que esté anotado por @Serializable class User {} @Encrypted) * alguna de las dos anotaciones Signaturas de métodos y constructores Table 1.6. Signaturas de métodos Patrón de la Descripción Ejemplos de métodos concordantes signatura public void Cualquier método público de la clase class User{ public void setName(String User.set*(*) User cuyo nombre comienze por set, name){} } cuyo tipo de retorno sea void, y que espere un único argumento public void Cualquier método público de la clase class User { public void updateInfo() User.*() User cuyo tipo de retorno sea void y que {}} no espere argumentos public * User.*() Cualquier método público de la clase class User{ public UserInfo User que no espera argumentos y getUserInfo(){}} retorna cualquier tipo public * User.*(..) Cualquier método público de la clase class User{ public UserInfo User que retorna cualquier tipo, y getUserInfo(){},public Date espera cualquier número y tipo de updatesBetween(Date first,Date last) argumentos (incluido cero) {}} * *.*(..) o * * (..) Cualquier método independiente de su Cualquier método del sistema tipo, del tipo de retorno, de su nombre y de los argumentos que espere !public * User.*(..) Cualquier método que no sea público class User {protected getUserInfo(){}} (privado,protegido o paquete) * * (..) throws Cualquier método que declare que clas AntlRBasedParser { public RecognitionException puede lanzar una excepción de tipo void parser(String file) throws RecognitionException RecognitionException} * User+.*(..) Cualquier método en la clase User y sus class UserDetails extends User {} subclases User Cualquier método del tipo UserService class UserService{public User UserService.*(..) cuyo tipo de retorno sea User. Si alguna retrieveUser(String name){}} class de las subclases sobreescribe el tipo DetailUserService extends de retorno con un subtipo de User UserService{public DetailedUser (mediante el tipo de retorno covariante retrieveUser(String name){}} introducido en Java 5) también será seleccionado. La signatura en el caso de los constructores difiere de la signatura de métodos en los siguientes aspectos: • Los constructores no tienen tipo de retorno por lo que no se permite utilizar el valor de retorno en la especificación de un pointcut de este tipo. • Dado que los nombres de los constructores no pueden ser libres (tienen que utilizar el mismo nombre de la clase), la parte de la signatura destinada al nombre será sustituida con la palabra new. • Por último, puesto que los constructores no pueden ser estáticos, no se podrá utilizar la palabra reservada static 15
  • 16. Aspect Oriented Programming Signaturas de campos Table 1.7. Signaturas de campos de clase Patrón de la Descripción Ejemplos de campos concordantes signatura private String Campo privado (tanto campo de una class User { private String username;} User.username instancia como estático) de la clase User * User.* Cualquier campo de la clase User class User{private String independiente de sus cualificadores, username;protected int credits;private tipo y nombre. UserDetails details;} * User+.* Cualquier campo de la El ejemplo de la fila anterior o class clase User y todas sus SpecificUser extends User {private subclases, independientemente de sus String address;} cualificadores, tipo y nombre. Implementación de pointcuts AspectJ ofrece dos mecanimos diferentes que permiten a los pointcuts realizar la selección de los joint points • Kinded pointcuts. En este caso, los pointcuts seleccionan categorías de joint points (de ahí su nombre). Así, por ejemplo, se ofrece la posibilidad de realizar matching sobre la ejecución de un método • Non-kinded pointcuts. Se seleccionan los joint point en base a la información de la que disponen, como los tipos en tiempo de ejecución o su contexto. En esta situación se seleccionan joint points de cualquier clase, siempre y cuando sastisfagan la condición descrita De nuevo, al igual que en el apartado anterior, veremos las diferentes opciones disponibles, tanto para los kinded como para los non-kinded pointcuts. Kinded pointcuts Table 1.8. Joint Points expuestos y tipos de pointcuts Categoría de Joint Point Sintaxis del pointcut Ejecución de un método execution(MethodSignature) Llamada a un método call(MethodSignature) Ejecución de un constructor execution(ConstructorSignature) Llamada a un constructor call(ConstructorSignature) Inicalización de una clase staticinitializaction(TypeSignature) Acceso de lectura a un campo get(FieldSignature) Acceso de escritura a un campo set(FieldSignature) Ejecución de un manejador de excepciones handler(TypeSignature) Inicialización de un objeto initialization(ConstructorSignature) Pre-inicialización de un objeto preinitialization(ConstructorSignature) Ejecución de un advice adviceexecution() Por ejemplo, si deseamos seleccionar todas las llamadas a los métodos públicos commit() de la clase TransactionManager, escribiríamos un pointcut similar al siguiente: call(public void TransactionManager.commit(. .)) 16
  • 17. Aspect Oriented Programming Non-kinded pointcuts Este tipo de pointctus permiten la selección de joint points basados en criterios adicionales a las signaturas vistas anteriormente. Por ejemplo, podremos seleccionar todos los joint point donde el objeto this es de un determinado tipo. Dicho joint point incluiría las llamadas a métodos, ejecuciones, manejadores de excepciones, etc. De nuevo, a través de ejemplos, veremos los diferentes tipos de non-kinded pointcuts ofrecios por AspectJ Non-kinded pointcuts basados en control de flujo Table 1.9. Non-kinded pointcuts basados en control de flujo Pointcut Descripción cflow(execution(* Selecciona todos los joint points en el flujo de la ejecución de TransactionManager.commit())) cualquier operación commit de la clase TransactionManager, incluyendo la ejecución del propio método. cflowbellow(execution(* Selecciona todos los joint points en el flujo de la ejecución de TransactionManager.commit())) cualquier operación commit de la clase TransactionManager, excluyendo la ejecución del método. cflow(execution(@Secured * * Todos los joint points en el flujo de la ejecución de cualquier (..))) método anotado con la anotación Secured cflow(transacted()) Cualquier joint point en el flujo de ejecución de los joint points seleccionados por el pointcut transacted() Non-kinded pointcuts basados en la estructura léxica Dentro de este tipo de pointcuts tenemos dos categorías: • within(TypeSingnature): selecciona cualquier joint point que aparece en el cuerpo de las clases y aspectos que concuerden con el tipo especificado. • withincode(ConstructorSignature),withincode(MethodSignature): selecciona cualquier joint point que aparezca dentre de un método o un constructor, incluendo la definición de cualquier clase local que puediera aparecer en los mismos. Table 1.10. Non-kinded pointcuts basados en la estructura léxica Pointcut Descripción within(User) Selecciona todos los joint points que aparecen dentro de la clase User within(User+) Selecciona todos los joint points que aparecen dentro de la clase user y cualquiera de sus clases derivadas within(@Transactional *) Selecciona todos los joint points que aparecen dentro de cualquier clase que se encuentre marcada con la notación Transactional withincode(* Selecciona todos los joint points que parecen dentro de cualquier TransactionManager.retrieve*(..)) método de la clase TransactionManager cuyo nombre comience por retrieve Non-kinded pointcuts de ejecución Este tipo de pointcuts nos permiten seleccionar joint points en base al tipo de los objetos en tiempo de ejecución. De este modo, disponemos de: • this(). Acepta dos formas diferentes: this(ObjectIdentifier) o this(Type). Seleccionará aquellos joint points cuyo objeto this sea del tipo (o el objeto) indicado. 17
  • 18. Aspect Oriented Programming • target(). Similar al concepto anterior, aunque en este caso, se utilizar el target del joint point en lugar del this Table 1.11. Pointctucts basados en la ejecución Pointcut Descripción this(User) Selecciona cualquier joint point en que se la expressión this instanceof User sea cierta. Así por ejemplo, seleccionará las llamadas a métodos o accesos a campos donde el objeto actual sea de tipo User o cualquier de sus subclases. target(User) Selecciona cualquier joint point en el que el objeto sobre el que se realiza la llamada al método es instanceof User Non-kinded pointcuts sobre argumentos Este tipo de pointcuts nos permiten seleccionar joint points en base al tipo de los argumentos en tiempo de ejecución. Veamos los distintos tipos de argumentos, en función del tipo del joint point : • En el caso de los joint points manejadores de excepciones el argumento será la excepción manejada. • En los métodos y constructores, los argumentos serán los argumentos del método y constructor • Los accesos de modificación de un campo, el argumento será el nuevo valor que va a tomar dicho campo. Table 1.12. Ejemplos de pointctucts basados en argumentos Pointcut Descripción args(User, . . , Selecciona cualquier joint point de tipo método o constructor en el que el primer String) argumento es de tipo User (o cualquiera de sus subclases), y el último argumento es de tipo String. args(SqlException) Selecciona cualquier joint point con un único argumento de tipo SqlException. Seleccionaría cualquier método o constructor que esperase un único argumento de tipo SqlException, un acceso de escritura a una campo estableciendo un nuevo valor de tipo SqlException, y también seleccinaría un manejador de excepciones de tipo SqlException Non-kinded pointcuts condicionales Este tipo de pointcuts nos permiten seleccionar joint points basados en una expresión condicional Table 1.13. Ejemplos de pointcuts condicionales Pointcut Descripción if(debug) Selecciona cualquier joint point donde el campo estático debug (en la definición del aspecto) toma el valor cierto 3 Crosscutting dinámico A lo largo de las secciones anteriores hemos analizado el modelo de joint point de AspectJ y la manera de defininir las reglas que nos permitan seleccionar aquellos joint points que sean de nuestro interés. Durante este capítulo analizaremos el modo en el que podemos alterar el comportamiento de nuestro sistema en los joint points que hayamos seleccionado mediante la definición de nuestros pointcuts. Descripción general Las reglas de tejido están compuestas de dos partes: 3 El término crosscuting representa la naturaleza transversal de las funcionalidades que estamos añadiendo. Se ha optado por no realizar la traducción del término y utilizar la terminología orginal 18
  • 19. Aspect Oriented Programming • advice: qué deseamos hacer • pointcuts: donde aplicamos el advice anterior AspectJ soporta el crosscutting dinámico mediante los advices, construcciones similares a los métodos que nos permiten definir las acciones que a ejecutar en los joint points seleccionados por un pointcut. Categorías de advices Dependiendo de las funcionalidades que estemos implementando necesitaremos ejecutar nuestra lógica en un determinado lugar del flujo de ejcución orginal; así por ejemplo, si estamos construyendo la seguridad de un sistema, nuestro código tendrá que verificar dicha seguridad antes de la ejecución del joint point. Si estuvieramos construyendo un sistema de cachés, nuestra nueva funcionalidad tendría que ejecutarse alrededor de joint point original, intentando recuperar el valor de la caché, y en caso de que no exista, ejecutar el código real y añadirlo a la misma para futuras invocaciones. AspectJ ofrece tres categorias de advices que satisfacen los escenarios anteriores (y alguno más): • Before Advice se ejecutan anteriormente a la ejecución del joint point • After Advice: se ejecutan posteriormente a la ejecución del joint point. Existen tres variantes diferentes • After finally se ejecuta tras la ejecución del join point independientemente del resultado de dicha ejecución • After returning se ejecuta tras la ejecución del joint point siempre y cuándo ésta última haya finalizado correctamente, es decir, sin lanzar ninguna excepción. • After throwing se ejecuta tras la ejecución fallida de un joint point, es decir, después de que dicho joint point dispare una excepción. • Around Advice rodean la ejecución del joint point. Sintaxis de los advices Aunque la sintaxis varía ligeramente dependiendo del tipo de advice que estemos escribiendo, podríamos dividir su estructura general en tres partes claramente diferenciadas: • Declaración del advice. En esta parte de la declaración se especifica el momento de ejecución del advice, es decir, si se ejecutará antes, después y alrededor de los joint points • Definición de los pointcuts. Se especifican los pointcuts sobre los que se desea actuar. • Cuerpo del advice. Definición del código a ejecutar una vez se haya alcanzado el joint point indicado. Veamos un ejemplo sencillo de definición de un advice: En primer lugar defininamos un sencillo pointcut pointcut secureOperation(User user): call( * User.*(..)) && target(user) En el pointcut anterior estamos capturando todas las llamadas a cualquier método de la clase User, y, adicionalmente estamos recogiendo el objeto que actua como target de la llamada. A continuación veremos un around advice para ilustrar la sintaxis: Object around(User user):secureOperation(user){ System.out.println("Securing operation on user " + user.toString()); 19
  • 20. Aspect Oriented Programming Object retValue = proceed(user); System.out.println("Finished secured operation on user " + user.toString()); return retValue; } En la definición anterior podemos ver la estructura de la declaración de un advice descrita anteriormente 1. La parte que precede a los dos puntos indica el momento de ejecución del advice (after,before,around). En este caso, se ejecutará alrededor del joint point seleccionado. 2. La parte que sigue a los dos puntos representa el pointcut, es decir, la definición de los criterios que determinan cuando se ejecutará el advice 3. La última parte representa el cuerpo del advice, es decir, el código que se ejecutará cuando alguno de los joint point definidos por el pointcut sea alcanzado. Advices y métodos Al igual que los métodos de una clase, los advices se utilizan para definir comportamiento. La sintaxis de éstos últimos es similar a la de los métodos aunque existen algunas diferencias dado que los advices son aplicados de manera automática, sin la necesidad de realizar explicitamente la invocación del mismo. Similitudes Analizemos las similitudes de ambos en tres categorías diferentes: declaración, cuerpo y comportamiento. La declaración de un advice es similar a la signatura de un método tradicional: • Opcionalmente puede asigarse un nombre al advice mediante el uso de la anotación @AdviceName • Recibe argumentos a través del contexto del joint point, que posteriormente podrán ser utilizados en el cuerpo para implementar la lógica necesaria. • Puede declarar el lanzamiento de una excepción. En cuerpo de los advices también es muy parecido al de los métodos: • El código del cuerpo del advice sigue las mismas reglas de acceso a miembros de otros tipos y/ o aspectos. • Se puede referenciar a la propia instancia del aspecto mediante el uso de this, • Los advices de tipo around pueden retornar un valor. • Los advices deben declarar las excepciones que sean checked que la implementación podría disparar. En el caso de los métodos, los advices : • No pueden declarar el disparo de una excepción que no está declarada en TODOS los joint points sobre los que actua • Pueden omitir algunas de las excepciones de tipo checked que han sido declaradas por alguno de los joint point sobre los que actua. • Pueden declarar el disparo de excepciones más específicas (de tipo checked) que las definidas por los joint point sobre los que está actuando. • Pueden lanzar cualquier tipo de excepción de tipo runtime. 20
  • 21. Aspect Oriented Programming Diferencias En comparación con los métodos, los advices: • La declaración de un nombre es opcional. • No pueden ser invocados directamente. • No presentan especificadores de acceso (relacionado con la característica de que no pueden ser invocados directamente) • No presentan un tipo de retorno en los advices de tipo before y after • Tienen acceso a unas cuantas variables en el propio aspecto: thisJointPoint,thisJointPointStaticPart,thisEnclosingJointPointStaticPart • Se puede utilizar la palabra reservada proceed en los advices de tipo around para ejecutar el joint point sobre el cual se está realizando el advice. Análisis detallado de los advices Hasta este momento disponemos de la información sobre las diferentes categorías de advices y su sintáxis general. A lo largo de las siguientes subsecciones profundizaremos en cada uno de los diferentes tipos de advices. Before advice Este tipo de advices se ejecutan antes de la ejecución del joint point sobre el que actúan. En el siguiente ejemplo: before():execution(@Secured * * (..)){ // asegurarse de que el usuario puede realizar la operación } el advice realiza una comprobación de seguridad antes de que se produzca la ejecución de cualquier método anotado con Secured. En caso de que el advice dispare una excepción, el joint point no se ejecutará. Este tipo de aspectos son comunmente utilizados en aspectos tales como seguridad o trazabilidad. After advice Se ejecutan después de la ejecución del joint point sobre el que actuan. Dentro de esta categoría, AspectJ ofrece tres tipos de advices: • Ejecución del advice independientemente del resultado de la ejecución del joint point. • Ejecución del advice única y exclusivamente si el joint point ha finalizado correctamente. • Ejecución del advice después que el joint point haya disparado una excepción. Veamos en detalle cada uno de los tres tipos anteriores: Advice After Este tipo de advices se ejecutan independientemente del resultado de la ejecución del joint point sobre el que actúan. Habitualmente se conoce a este tipo de advices como after finally puesto que su semántica es similar a la de un bloque finally. El siguiente advice: after(): call(@Logging * ServiceManager.*(..)){ // registrar el resultado de la operación 21
  • 22. Aspect Oriented Programming } registra el resultado de todas las operaciones de la clase ServiceManager que estén marcadas con la anotación Loggin, independientemente si retornan correctamente o terminan su ejecución de forma inesperada mediante el disparo de una excepción. Advice After Returning En muchas ocasiones,será necesario ejecutar el código de nuestro advice única y exclusivamente cuando la ejecución del joint point haya terminado de forma correcta. Continuando con el ejemplo anterior: after () returning: call(@Logging * ServiceManager.*(..)){ // registrar el resultado de la operación } se seguirá registrando el resultado de las operaciones, siempre y cuando, la ejecución haya terminado correctamente, sin el disparo de ninguna excepción. AspectJ ofrece una pequeña variante para este tipo de advices: after() returning (ReturnType returnObject) gracias a la cual se permite recuperar el objeto retornado por la ejecución del joint point dentro del advice. Veamos un pequeño ejemplo ilustrativo: after() returning (java.sql.Connection connection): call(java.sql.Connection DriverManager.getConnection(..)){ System.out.println("Se ha recuperado la conexión " + connection); } Es importante tener claro que no se puede retornar un objeto nuevo (si que lo podemos modificar, pero no retornar uno nuevo). Advice After Exception Este tipo de advices son similares a los descritos en el apartado anterior. En este caso, el advice se ejecutará única y exclusivamente cuando el joint point dispare una excepción. Presentan la siguiente estructura: after() throwing:execution (* ServiceManager+.*(..)) El advice del ejemplo anterior se ejecutará siempre y cuando algún método de la clase ServiceManager (o alguna de sus subclases), dispare una excepción. En el supuesto de que la ejecución del joint point termine correctamente, este tipo de advices no serán ejecutados. Al igual que los advices del apartado anterior, AspectJ ofrece una modo de recuperar la excepción que ha sido disparada por el joint point de modo que esté disponible en el cuerpo del advice. Siguiendo una sintáxis similar a la anterior, tendríamos: after() throwing (ExceptionType exceptionObject): Un after throwing advice nunca podrá tragarse la excepción;por lo que seguirá subiendo por la pila de llamadas hasta llegar al objeto que realizó la invocación del joint point. Around advice Este clase de advices engloban al joint point, pudiendo ejecutar la lógica del mismo un número indefinido de veces. Incluso pueden omitir la ejecución del propio joint point. Algunos de los usos principales de este tipo de advices son los siguientes: 22
  • 23. Aspect Oriented Programming • Ejecución de lógica adicional antes y después de la ejecución de un joint point, como por ejemplo, acciones de profiling. • Omitir la ejecución original, y realizar otra en su lugar, como por ejemplo, operaciones con cachés. • Envolver la operación con una gestión de excepciones, con el objetivo de aplicar una política de gestión de excepciones. Un ejemplo de este uso sería la gestión de transacciones. Este advice ofrece una potencia superior a todos los advices vistos hasta el momento, puesto que podrían sustituir a los anteriores. De todos modos, se considera una buena práctica utilizar el advice más sencillo que cumpla las necesidades de la tarea que necesitamos llevar a cabo. Ejecución del joint point Si desde el around advice deseamos llevar a cabo la ejecución del joint point, tendremos que hacer uso de la palabra reservada proceed() dentro del cuerpo del advice. Debemos recordar, que, puesto que la invocación de proceed() ejecuta el joint point, tendremos que pasarle el mismo número de argumentos que han sido recolectados por el advice. Asimismo, puesto que la invocación de proceed() supone la ejecución del joint point, el valor de retorno será el retornado por éste último. Veamos un pequeño ejemplo de utilización de advices de este tipo: void around(User user,int credits) throws InsufficientCreditsException: call(* User.pay*(int)) && target(user) & & args(credits){ try { proceed(user,credits); }catch(InsufficientCreditsException ex){ if(!processException()){ throw ex; } } Analicemos en detalle la construcción anterior: 1. El pointcut selecciona cualquier llamada a los métodos de la clase User cuyo nombre comienze por pay y disparen una excepción de tipo InsufficientCreditsException 2. La segunda parte del pointcut recolecta el contexto del joint point: el usuario sobre el que se está realizando la llamada y el número de créditos que se están pasando como argumento del método que se está ejecutando. 3. En el cuerpo del advice, se engloba la ejecución del método con un bloque de gestión de excepciones, para realizar una protección adicional en caso de que se produzca una excepción. En el caso de que la protección adicional no sea correcta, la excepción será disparada de nuevo. Retornando valores Todos los around advices deben declarar un valor de retorno (puediendo ser void). Habitualmente el tipo de retorno de éstos se corresponde con el tipo de retorno de los joint points sobre los que está actuando. En algunas ocasiones, todos los joint points sobre los que actua el advice no presentan el mismo tipo de retorno, como puede ocurrir cuando estamos añadiendo soporte transaccional a diferentes operaciones. En estas situaciones el tipo de retorno que debe declarar el advice será Object. AspectJ acomodará el valor de retorno de acuerdo a las siguientes reglas: • Si se está retornando un tipo primitivo, AspectJ realizará el boxing/unboxing correspondiente. Esta característica es similar a la incluida a partir de Java 5, pero AspectJ no precisa de dicha versión de Java para realizar la operación. 23
  • 24. Aspect Oriented Programming • En el caso en el que el tipo de retorno no sea primitivo, AspectJ realizará los casts oportunos antes de retornar el valor. Contexto del joint point Muchas ocasiones es necesario acceder a los objetos que conforman la ejecución del joint point para que el advice pueda llevar a cabo la lógica correspondiente. Por tanto, los pointcuts, necesitan exponer el contexto disponible en la ejecución del joint point de modo que pueda estar disponible en el cuerpo del advice. Dicho contexto puede definirse de dos modos diferentes: • Objetos (incluyendo los tipos primitivos) que conforman el joint point • Anotaciones asociadas al joint point La siguiente tabla describe el cojunto de pointcuts que AspectJ ofrece para recuerar el contexto en los joint points. Table 1.14. Pointcuts para recuperar el contexto en un joint point Pointcut Contexto recuperado this(obj) Objecto this en el joint point que se está ejecutando target(obj) Objetivo de la llamada en el joint point que se está ejecutando. En el caso de un joint point de una llamada a un método, el target será el objeto que realiza la llamada. Para la ejecución de un método, el target será el objeto this. En los accesos a campos, el target será el objeto que se está accediendo. En el resto de joint points no existen un target disponible args(obj1,obj2,...) Objetos que representa los argumentos en el joint point. Para las llamadas/ ejecuciones de métodos/constructores, recupera los argumentos de los mismo. En el caso de los manejadores de excepciones, recupera la excepción producida. Para los accesos en modo escritura a un campo, recupera el nuevo valor del campo. @this(annot) Anotación asociada con el tipo del objeto this del joint point @target(annot) Anotación asociada con el tipo del objeto target del joint point @args(annot1,annot2,...)Anotación asociada con el tipo de los argumentos del joint point @within(annot) Anotación asociada con el tipo "enclosing" del joint point @withincode(annot) Anotación asociada con el método "enclosing" del joint point annotation(annot) Anotación asociada con el asunto actual del joint point. Aspectos Los aspectos representan la únidad básica de modularización en el mundo de la orientación a aspectos en general, y en AspectJ, en particular. Los siguientes subapartados nos mostrarán una definición más formal que la vista hasta este momento.4 Analizaremos en detalle los aspectos, realizaremos una comparativa con las clases y veremos como nos pueden ayudar a modularizar y construir componentes reutilizables. Trabajando con aspectos Los aspectos son las construcciones encargadas de encapular la implementación de todos los conceptos transversales. Será el weaver el encargado de modificar el comportamiento del núcleo del sistema en función de la información definida en nuestros aspectos. 4 Seguiremos analizando los nuevos conceptos, al igual que en las secciones anteriores, desde elpunto de vista de la sintaxis tradicional, dejando un poco de lado la sintaxis @AspectJ 24
  • 25. Aspect Oriented Programming La sintaxis general de un aspecto es la siguiente: [access specification][abstract] aspect <AspectName> [extends class or aspect] [implements interface-list] [ [<association-speficier>(Pointcut)] | [pertypewithin(TypePattern) ] ]{ // aspect body } La palabra reservada aspect permite realizar la declaración de un nuevo aspecto. Cada uno de estos aspectos presenta las siguientes características: • Presenta un nombre para podere referirse a él desde otras partes del código. • Puede presentar especificadores de acceso (public,proteced o private) • Puede ser abstract • Puede aplicar el mecanismo de herencia, derivando de otros aspectos o de clases tradicionales. Asimismo puede implementar interfaces. • Puede especificar el modelo de instanciación • Su cuerpo puede estar compuesto por definiciones de pointcuts, miembros o tipos anidados. Diferencias con las clases A la vista del apartado anterior, en un principio, parece que las clases y los aspectos son prácticamente lo mismo, pero no es así, los aspectos no son clases. A continuación se describen algunas de las diferencias principales: Modelo de instanciación Es el sistema el encargado de la instanciación de los aspectos. En resumen, nunca utilizaremos la palabra reservada new para crear una instancia de un aspecto Restricciones en el mecanismo de herencia Los aspectos no pueden derivar de otros aspectos concretos, es decir, sólo pueden derivar de aspectos definidos como abstract. Esto es una restricción que se incluyó en la definición del lenguaje para evitar complejidades innecesarias. Parámetros genéricos Los aspectos concretos no pueden declarar parámetros genéricos, sólo aquellos marcados como abstract podran hacerlo. El motivo es el modelo de instanciación, puesto que, como los aspectos son instanciados por el sistema, éste último no es capaz de realizar la inferencia de tipos. privileged Los aspectos pueden ser definidos con el especificador de acceso privileged, el cuál otorga la capacidad de acceder a los miembros privados de las clases sobre las que se está actuando. Resumen Nos hemos introducido en el mundo AOP, hemos analizado su evolución a lo largo a lo largo del Hype Cycle, visto sus usos en el mundo real y hemos realizado un estudio de sus principales componentes y el modo en el que se utilizan cada uno de ellos. 25
  • 26. Aspect Oriented Programming Evidentemente, esto pretende ser un primer acercamiento al mundo de AOP, y concretamente a AspectJ, a través del cual el lector pueda comprender los beneficios de esta tecnología y le permita utilizarlo para escribir sus propios programas. Soy consciente de que se han quedado muchas cosas en el tintero, que darían cabida para un libro completo, por lo que a continuación se enumeran algunas de ellas para las mentes inquietas que deseen profundizar en otros aspectos que no tienen cabida en este documento: • Técnicas como static crosscutting tales como: • Introducción de nuevos miembros en una clase • Complemento de anotaciones • Modificación de jerarquías de tipos • Respuesta a errores y warnings en tiempo de compilación • Debilitado de excepciones • Asociación y predencia de aspectos • Sintáxis @AspectJ • Análisis detallado de los procesos de weaving • Integración con Spring • ... Para una análisis exhaustivo de estos y otros muchos aspectos, el usuario puede acudir a la sección bibliografía El objetivo de este introducción no era dar una visión teórica y aburrida de AspectJ sino dar una visión pragmática del mismo. De este modo, la siguiente sección ilustrará la mayoría de conceptos vistos anteriormente mediante una serie de ejemplos reales. Ejemplos reales Hasta este momento hemos visto las posibilidades que nos ofrece AOP en general, y AspectJ en particular, mediante la exploración de sus elementos, sintáxis y ejemplos sencillos. Los siguientes subapartados ofrecerán un conjunto de ejemplos reales de aplicación de la tecnología así como algunos patrones habituales. La estructura de los ejemplos será la siguiente: se planteará un problema, se dará una solución general, y después se propondrá una alternativa basada en AOP y AspectJ. Pongámonos manos a la obra. 5 Patrón wormhole Este patrón consiste, básicamente, en habilitar un contexto de información desde un llamante a un llamado sin la necesidad de pasar dicha información como un conjunto de argumentos a lo largo de todas las invocaciones del los diferentes métodos del flujo de ejecución. Imaginemos por un momento que estamos implementando un sistema de seguridad en el que cada uno de los métodos tiene que comprobar quien les ha invocado para determinar si se les permite ejecutar la operación. Creando un canal de comunicación directa entre dos niveles cualesquiera en la pila de llamadas, nos evitará tener que ir moviendo la información necesaria por cada una de las capas. De este modo, evitaremos la necesidad de modificar la cadena de llamadas cuando necesitemos añadir algún parámetro adicional al contexto de información. 5 De nuevo, se ha optado por mantener la nomenclartura original del patrón, sin realizar una traducción al castellano, puesto que considero que el resultado de dicha traducción no resultaría demasiado intuitiva para el lector. 26
  • 27. Aspect Oriented Programming Solución tradicional Sin la utilización de una tecnología como AOP disponemos de dos alternativas de solución. La primera de ellas movería toda la información necesaria a lo largo del contexto de llamadas añadiendo los parámetros que fueran necesarios, mientras que la segunda, haría uso de un almacenamiento espefíco de los hilos. La solución que pasa a través de parámetros el contexto de información necesario produce una contaminación del API, puesto que cada uno de los métodos que intervienen en el flujo que transcurre desde el llamante hasta el llamado necesitará de parámetros adicionales que permitan mover dicha información a lo largo de la pila de llamadas. La segunda solución propuesta, el uso de un almacenamiento específico, pasaría porque el llamante crease una variable ThreadLocal en la que se almacenase toda la información necesaria. Aunque esta segunda solución evita la contaminación del API, se necesita modicar tanto el llamante como el llamado, además de requerir un conocimiento de cómo se almacena el contexto de información. Descripción general La siguiente figura ilustra la idea básica de este patrón arquitectónico: Figure 1.5. Diagrama arquitectónico del patrón wormhole La idea general consiste en indentificar dos pointcuts: uno en el llamado y otro en el llamante. El primero de ellos será el encargado de recolectar toda la información que será transmitida a lo largo del "aguejero de gusano". El segundo pointcut tendrá que especificar aquellos joint point del llamado en los que debe actuar el wormhole. En la imagen anterior cada una de las cajas trasnversales representa un nivel en la pila de llamadas. Habitualemente, para comunicar el llamante y el llamado tendríamos que ir pasando toda la información de nivel en nivel, hasta que alcanzásemos el nivel deseado. El patrón descrito en esta sección establece un canal de comunicación directo a lo largo de todos los niveles de llamadas, evitando el paso de información nivel a nivel. Plantilla A continuación se propone una plantilla de solución que puede ser utilizada como base para la implementación de este patrón en nuestros sistemas 27
  • 28. Aspect Oriented Programming public aspect WormholeAspect { pointcut callerSpace(caller context) : <caller pointcut> ; pointcut calleeSpace(callee context) : <callee pointcut> ; pointcut wormhole(<caller context>, <callee context>) : cflow(callerSpace(<caller context>)) && calleeSpace(<callee context<); // advices para el wormhole around(<caller context>, <callee context>) : wormhole(<caller context>, <callee context>) { // ... advice body } } En la plantilla anterior, los dos primeros pointcuts recolectan los contextos en el llamante y en el llamado respectivamente. El tercero de ellos construye el wormhole entre los dos espacios, capturando todos los joint point determinados por el pointcut calleeSpace que se encuentren en el flujo de ejecución de aquellos joint points capturados por el pointcut callerSpace. Puede que con un ejemplo nos queden las cosas un poquito más claras. Escribamos un pequeño aspecto que genere un canal de comunicación entre un sistema iniciador de transacciones y las ejecuciones de una query: public aspect SqlTransactionAspect { pointcut transactionSystemUsage(TransactionSystem ts) : execution(* TransactionSystem.*(..)) && this(ts) pointcut queryExecutions(SqlQuery query, String[ ] params) : this(query) && args(params) && execution(public * SqlQuery.exec*(String [ ])); pointcut wormhole(TransactionSystem ts, SqlQuery query, String[ ] params) : cflow(transactionSystemUsage(ts)) && queryExecutions(query, params); before(TransactionSystem ts, SqlQuery query, String[ ] params) returning : wormhole(ts, query, params) { // realizar las operaciones deseadas } • El pointcut transactionSystemUsage captura todos los joint point de ejecución en de la clase TransactionSystem. Además recolecta el objeto en si en el contexto de ejecución. • El pointcut queryExecutions() captura todas las llamadas a los métodos exec de la clase SqlQuery y recolecta la propia query y los argumentos • El pointcut wormhole genera un canal de comunicación directo entre el el sistema de transacciones y la ejecución de la query, capturando todos los joint points que se produzcan bajo el flujo de ejecución de transactionSystemUsage. Además, se captura el contexto de los dos pointcuts constituyentes. • El advice que actua sobre el pointcut wormhole dispone ahora de toda la información: la query y sus parámetros así como el sistema de trasancciones 28
  • 29. Aspect Oriented Programming Hilos seguros La amplia difusión de los procesadores con múltiples núcleos, el uso de lenguajes especialidados como Erlang o Haskell, y la popularidad de numeros libros al respecto, han logrado que los sistemas de software alcancen niveles de concurrencia insospechados hasta hace poco tiempo. Si embargo, para muchos desarrolladores, incluso gente experimentada,la concurrencia supone un auténtico misterio. Implementar un sistema que presente un control de concurrencia es una tarea complicada, dado que, en muchas ocasiones, los conceptos se difuminan a lo largo de diferentes módulos. Estas circunstancias pueden ocasionar, la construcción de sistemas no demasiado ricos, con erros aparentes, caídas del sistema inesperadas, integridad comprometid, deadlocks, . . . Por norma general, la implementación de un sistema de concurrencia basado en los patrones arquitectónicos y de diseño apropiados suele ocasionar sistemas mucho más fiables que los descritos en el párrafo anterior. Muchos de los patrones de concurrencia presentan numerosos conceptos trasnversales, por lo que AOP puede ayudarnos a simplificar su diseño y posterior implementación. En este ejemplo, analizaremos el patrón read-write lock. La implentación clásica de este patrón supone la adición de código en todos aquellos métodos que necesiten modificar el estado de un objeto. Los siguientes subapartados nos mostarán como podemos realizar una implementación modular de este patrón basado en AspectJ. Implementación tradicional. Este patrón utiliza un par de bloqueos (locks): el bloqueo de lectura, y el bloqueo de escritura. Múltiples hilos lectores podrán adquirir el bloqueo de lectura siempre y cuando el bloqueo de escritura no haya sido adquirido. El otro bloqueo, el de escritura, únicamente podrá ser adquirido siempre y cuando ninguno de los hilos restantes haya tomado posesión del bloqueo de escritura. La siguiente clase ilustra, mediante una pequeña clase de ejemplo, la solución anterior. // package definition . . . import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author migue * */ public abstract class User { protected String username; protected String login; protected int credits; public User(int credits) { this.credits = credits; } private ReadWriteLock lock = new ReentrantReadWriteLock(); public void increaseCredit(int credit) { // adquirmos el bloqueo de lectura this.lock.writeLock().lock(); try { 29
  • 30. Aspect Oriented Programming // realizamos la operación, en este caso, // aumentar el crédito del usuario this.credits += credit; } finally { // liberamos el recurso adquirido this.lock.writeLock().unlock(); } } public void decreaseCredit(int credit) { // adquirmos el bloqueo de lectura this.lock.writeLock().lock(); try { // realizamos la operación, en este caso, // disminuir el crédito del usuario this.credits -= credit; } finally { // liberamos el recurso adquirido this.lock.writeLock().unlock(); } } public boolean hasCredit() { // adquirimos el bloqueo de lectura this.lock.readLock().lock(); boolean hasCredit; try { hasCredit = this.credits > 0 ? true : false; } finally { this.lock.readLock().unlock(); } return hasCredit; } } Resulta evidente que la manera anterior de realizar los bloqueos resulta intrusiva, puesto que para cada uno de los métodos para los que en los que se desee gestionar la gestión de la concurrencia, tendremos que añadir los fragmentos de código vistos en el ejemplo. Cualquier método en el que nos olvidemos de añadir el código de gestió de la concurrencia puede ocasionarnos un incorrecto funcionamiento de nuestro sistema. Además, debemos asegurarnos que si un método adquire el bloqueo de lectura, sea este el que libere, y no el de lectura, y viceversa. Implementación basada en AspectJ Esta alternativa de solución propone a creación de un aspecto que encapule toda la lógica del patrón descrito; evitando de este modo la modificación de todas aquellas clases que necesiten hacer uso de diho patrón. Puesto que además, el patrón es reutilizable en numerosas situaciones, haremos que el aspecto también lo sea. La base de la solución, tal y como se indicaba anteriormente, consiste en disponer de un aspecto abstracto que implemente toda la lógica del patrón: public abstract aspect ReadWriteLockSynchronizationAspect perthis(readOperations() || writeOperations()) { 30