Você está na página 1de 34

Chapter 1.

Aspect Oriented Programming


Table of Contents
Motivaciones ................................................................................................................ 1 Evolucin de las metodologas de programacin ................................................................ 3 AOP en el mundo real ................................................................................................... 4 Hype Cycle .......................................................................................................... 4 Dnde se utiliza AOP? ......................................................................................... 6 Introduccin a AOP ...................................................................................................... 7 Metodologa AOP ................................................................................................. 7 Anatoma de un lenguaje orientado a aspectos ........................................................... 8 Beneficios de la metodologa AOP ........................................................................... 9 Verdades y mentiras sobre AOP ............................................................................ 10 Visin general de AspectJ ............................................................................................. 11 Introduccin a AspectJ ......................................................................................... 11 Modelo de Joint Point ......................................................................................... 11 Crosscutting dinmico .......................................................................................... 18 Aspectos ............................................................................................................ 24 Resumen ............................................................................................................ 25 Ejemplos reales ................................................................................................... 26 Bibliografa ................................................................................................................ 33

Motivaciones
Antes de profundizar en la temtica propia de la orientacin a aspectos y sus aplicaciones en el mundo real, sera conveniente describir las motivaciones principales que han ocasionado la escritura de este captulo de la memoria. La primera de ellas ha sido la intencin de introducir al lector en algunas de las tcnicas de desarrollo avanzadas utilizadas en la actualidad por los equipos de desarrollo de software ms vanguardistas. La segunda est relacionada con el desarrollo de nuevas herramientas de programacin y, por ende, con la herramienta desarrollada como ejemplo de este proyecto: R-Eclipse. Si el lector desconoce muchos de los trminos definidos en esta seccin no se preocupe, a lo largo del captulo comprender la terminologa aqu utilizada. En los ltimos aos han surgido muchos lenguajes similares a Java que se ejecutan sobre la propia mquina 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 solucin JDT, no ofrecen soporte para la integracin de estos nuevos lenguajes en su modelo Java subyacente. Por ejemplo, no existe un modo de incluir jerarquas de tipos,jerarquas de llamadas, etc.

R Eclipse no ha utilizado el enfoque descrito en esta seccin por dos motivos principalmente; el primero de ellos es que R no es un lenguaje similar a Java ni corre bajo su mquina virtual. El segundo de ellos consiste en que el framework base de desarrollo, DLTK, no utiliza la arquitectura descrita en estas lneas.

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 indexacin de cdigo fuente. No se puede. Necesidad de acoplarse al parser de JDT. No se puede. Una aproximacin utilizada por muchos entornos de desarrollo de lenguajes actuales como pueden ser Scala o Groovy es la utilizacin del servicio de tejido de JDT. Las caractersticas principales son: Utiliza AspectJ aadiendo puntos de unin al modelo JDT Se encapsula en puntos de extensin de Eclipse, hacindolo 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 grfico ilustra como funciona el proceso anterior:

Aspect Oriented Programming

Figure 1.2. Proceso de acoplamiento al JDT

A lo largo de las siguentes secciones se introducir la terminologa AOP as como la definicin de sus elementos ms relevantes.

Evolucin de las metodologas de programacin


La ingeniera del software ha recorrido un largo camino desde sus inicios: desde el cdigo mquina hasta la orientacin a objetos pasando por los lenguajes procedimentales. Analizando de manera somera la evolucin de las metodologas de programacin observamos cmo el modelo procedimental introdujo la abstraccin funcional y la orientacin a objetos los conceptos de composicin, reutilizacin y encapsulacin. 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 programacin utilizado en la mayor parte de los grandes desarrollos de software. Entre todas las ventajas del paradigma de orientacin a objetos, en el prrafo anterior se destacaba, no al azar, la reutilizacin y la encapsulacin pero . . . siempre es posible ubicar en el mismo lugar todas las tareas relacionadas con una misma funcin?, en alguna ocasin has visto un fragmento de cdigo que no encaja en ninguna clase en particular?. Imaginemos un sistema en el que determinadas operaciones necesitan llevar a cabo una gestin de transacciones. Resultara sumamente complicado,por no decir imposible, modularizar todos los conceptos necesarios en un sistema transaccional: inicializacin, comunicacin con el manager de transacciones, rollbacks, . . . Esto es debido a que todos los mtodos de un objeto que requieren un control de transacciones necesitan ser conscientes que la operacin a realizar se ejecuta bajo un control transaccional, para comportarse de manera acorde al funcionamiento requerido. Resumiendo, el cdigo encargado de la gestin de transacciones estara ubicado en cada uno de los objetos que lo necesite. La solucin comunmente adoptada a este problema es copiar y pegar el cdigo en todas aquellas partes en las que es necesario, resultando evidente, que dicha solucin no permite disponer de una buena modularizacin y dificulta las labores de mantenimiento y evolucin del cdigo. Este

Aspect Oriented Programming

fenmeno es conocido como scattering , puesto que el cdigo relacionado con un mismo asunto se encuentra repartido a lo largo de todo el sistema. Sumemos, adems, que los mdulos que contienen cdigo relativo a muchos asuntos diferentes tienden a ser, en general, menos reutilizables. El fenmeno en el que diferentes asuntos son entremezclados en el cdigo se conoce como tangling . La problemtica introducida en los prrafos anteriores, tangling y scattering , afecta al diseo y desarrollo de software de muchas y diferentes maneras. Veamos alguna de las principales: Trazabilidad reducida. La implementacin de diferentes conceptos en un mismo lugar dificulta el proceso de establecimiento de una relacin entre los requisitos y su implementacin y viceversa. As por ejemplo, para completar la trazabilidad del requerimiento de autenticacin podramos llegar a examinar todos los mdulos del sistema. Baja producitividad. Varios conceptos no relacionados que han sido implementados en un mismo lugar ocasiona que la atencin 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 construccin de un mdulo implicar la participacin de diversos desarrolladores, con diferentes perfiles, o que el desarrollador tenga conocimiento en todos los mbitos que se estn incluyendo en el nuevo mdulo. Escasa reutilizacin del cdigo. Los conceptos implementados en un mdulo podran ser requeridos por otros mdulos con funcionalidades similares Baja calidad. El code tangling provoca que el cdigo sea ms difcil de leer, de ubicar los potenciales problemas y de hacer revisiones del mismo. Por ejemplo, la revisin de cdigo de un mdulo en el que se implementan diversos conceptos requerir la presencia de expertos en cada uno de ellos. A menudo muchos de estos expertos no estarn disponibles de manera simultnea, y el resto no prestar demasiada atencin en los temas que se encuentren fuera de su rea de conocimiento. Dificultad para llevar a cabo evoluciones. La falta de recursos o una visin incompleta derivan en un diseo que maneja nicamente los conceptos actuales. Cuando aparezcan nuevos requerimientos,a menudo, nos veremos obligados a reimplementar. Dado que la implementacin no se encuentra modularizada,la inclusin de un nuevo requerimiento podra obligar a realizar cambios en todos los mdulos. Los problemas descritos en los puntos anteriores han servido como impulso en la bsqueda de nuevos y mejores enfoques en la arquitectura, diseo e implementacin. AOP ofrece una solucin a todos los problemas anteriores.

AOP en el mundo real


Qu lugar ocupa la orientacin a aspectos en el mundo real? Deberamos prestarle atencin o ignorarlo por completo? Cules son los beneficios aportados? y los posibles riesgos de adopcin de esta tecnologa?. Estas y otras preguntas sern respondidas, desde un punto de vista prctico, en los siguientes subapartados de esta seccin.

Hype Cycle
Hype Cycle es una representacin grfica del grado de madurez, adopcin y aplicacin en el mundo real de una tecnologa determinada. Es importante comprender bien el grfico anterior, y la posicin de la tecnologa que se est considerando; en este caso, AOP, puesto que se dispondr de una visin mucho ms ajustada de los riesgos y beneficios a los que nos estamos exponiendo.

Aspect Oriented Programming

Figure 1.3. Diagrama de componentes de R-Eclipse

La interpretacin de la curva Hype Cicle implica cinco fases diferentes las cuales analizaremos a continuacin, relacionndolas, evidentemente con AOP.

Activacin de la tecnologa
Este es el momento en el que la tecnologa aparece con la intencin/promesa de solucionar un conjunto determinado de problemas. Podra ser el anuncio de un nuevo producto o la liberacin de una nueva versin de un producto ya existente. En el caso de AOP, este proceso de activacin se produjo en 2002 con el lanzamiento de AspectJ 1.0, seguido de una liberacin mucho ms importante (AspectJ 1.1) en el ao 2003. Mucha gente se dio cuenta del potencial de AspectJ, especialmente su utilizacin en aplicaciones empresariales.

Expectativas irreales ("peak")


Durante esta fase la tecnloga se hace muy popular. Todo el mundo quiere conocerla y tiene una opinin sobre ella aunque muy poca gente la utiliza en aplicaciones reales. Durante el ao 2004 la mayora de desarrolladores que trabajaban en Aspectj y AspectJ Development Tools (AJDT) eran integrantes de IBM. Esta inversin por parte de IBM proporcion una base slida a AspectJ. La ausencia de una adopcin masiva hizo que el uso de la tecnologa se conviertiese en una autntica 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 gestin provoc un pico ms bajo en el hype cycle, lo que supuso una cada mucho menor en la siguiente fase.

Desilusin
Esta es la fase de ciclo Hype en la que la tecnologa comienza a perder toda la atencin que se le haba prestado hasta el momento. Mientras que los equipos que la adoptaron desde sus inicios continuan utilizndola con el objetivo de obtener una ventaja competitiva, muchos otros comienzan a observarla con cierto escepticismo. Nuevas tecnologas aparecen en escena aportando soluciones diferentes al mismo problema. Resulta

Aspect Oriented Programming

interesante destacar que muchos de estos nuevos competidores estn en la fase de "expectativas irreales". AOP atraves esta fase durante 2006 aproximadamente. Enterprise Java Beans ofreca 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 ms importante. La aparicin de lenguajes dinmicos como Groovy o Ruby y sus frameworks asociados, Grails y Rails, supuso una dura competencia para AOP. El modelo de metaprogramacin del que disponen estas tecnologas facilitaba una nueva solucin para realizar la modularizacin de funciones transversales.

Viendo la luz
Numerosos factores intervienen en el desarrollo de esta fase: maduracin de la tecnologa, cambios en la misma para acercarse a la realidad, bsqueda de un contexto de uso en el que realmente se cause impacto o la "desilusin" 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 lderes del proyecto abandonaron IBM para fichar por SpringSource:Adrian Colyer,Andy Clement, Andrew Eisinberg, . . ., conviertiendo a AspectJ en un proyecto ms del portfolio de Spring. Analicemos los factores enumerados anteriormente: Acercamiento a la realidad:La introduccin de anotaciones en Java 5, los cambios en la sintxis o la supresin 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 utilizacin: la influencia de Spring: En sus inicios AspectJ careca de un contexto de utilizacin 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. Desilusin con los competidores: Anteriormente indicamos que EJB permita modularizar los conceptos transversales de un sistema. Los desarrolladores se dieron cuenta de que la solucin ofrecida era demasiado pesada en la mayora de las ocasiones. La versin 3 de EJB introdujo interceptores, un concepto similar a los advices de AspectJ, aunque carecan de un modelo de unin. Los lenguajes dinmicos 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 evolucin de los mismos, y ver cmo contina evolucionando AspectJ.

Plena productividad
Es la ltima fase definida en el ciclo Hype. En esta situacin la tecnologa est ampliamente difundida y se utiliza en las solucin de problemas para los que ofrece una gran respuesta. Ser en esta fase cuando se produzca una aceptacin mavisa de la tecnologa. En la actualidad,Java o C , se encuentran en esta fase. AOP y AspectJ debern alcanzar este nivel con el paso del tiempo.

Dnde se utiliza AOP?


A continuacin se analizarn algunos de los principales mbitos de aplicacin de AOP

Aplicaciones empresariales
Gestin de transacciones, seguridad, auditora, monitorizacin, gestin de la concurrencia, manejo de errores y un largo ectera son funcionalidades transversales en la mayora de aplicaciones empresariales.

Aspect Oriented Programming

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

Web y servidores de aplicaciones


Aplicacin de polticas, FFDC, recoleccin de contextos,trazabilidad o monitorizacin 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
Gestin de transacciones y seguridad son habitualmente implementadas mediante aspectos. Asimismo, otras utilizaciones de los aspectos podra ser la inyeccin de dependencias en objetos de dominio. Para obtener un amplio abanico de posibilidades de uso de los aspectos, el lector podra visitar los proyectos de Spring Roo o Apache Magma.

Herramientas de monitorizacin
El uso de aspectos facilita tambin la construccin de herramientas de monitorizacin. Muchas herramientas utilizan AspectJ como tecnologa subyacente: Glassbox,Perf4J,Contract4J,JXInsight o MaintainJ son algunos de los ejemplos.

Compiladores e integracin de IDE's


El mismo equipo de AspectJ utiliza la propia tecnologa para extender el compilador de JDT de manera que sea capaz de sopotar las nuevas construcciones. AJDT utilizan un proceso de weaving a travs de una implementacin basada en OSGI ofrecida por el proyecto Equinox. Scala IDE en Eclipse utiliza un enfoque similar para la construccin del entorno de desarrollo.2

Introduccin a AOP
AOP se construye sobre metodologas existentes como OOP o programacin funcional, mejorndolas con las construcciones necesarias que permiten modularizar correctamente los conceptos transversales. Por ejemplo, si se trabaja con OOP, el ncleo de nuestro sistema ser implementado mediante la utilizacin de clases. Los aspectos sern los encargados de representar las funcionalidades transversales y determinar cmo todos los diferentes mdulos debern ser tejidos para construir el sistema final.

Metodologa AOP
Desarrollar un sistema utilizando AOP es similar a un desarrollo basado en otras metodologas: determinar los requerimientos, implementarlos y construir el sistema final mediante la combinacin de los mismos. La comunidad AOP define tres pasos: 1. Descomposicin en aspectos En este paso se indentificarn los diferentes concerns , tanto los transversales como los que componen el ncleo. Por ejemplo, en una capa de negocio encargada de calcular el IVA total de los productos los aspectos pertenecientes al ncleo sera el clculo del IVA en s, mientras que elementos como la transaccionalidad, registro de actividad,seguridad en hilos, manejo de cachs, . . . seran conceptos de un espectro mucho ms amplio, que sern necesitados en otros muchos mdulos del sistema, y por tanto, se categorizan como conceptos transversales 2. Implementacin de "concerns" En este punto tendr que realizarse la implementacin de los diferentes requerimientos de manera independiente . Siguiendo con el ejemplo anterior, un grupo
2

Ver la seccin inicial de este captulo

Aspect Oriented Programming

sera el encargado de realizar la implementacin del mdulo de lgica de negocio encargado de calcular el IVA, otro grupo llevara a cabo la gestin del logging, un tercer grupo sera el encargado de asegurarse que las operaciones fuesen thread safe , y as sucesivamente. 3. Recomposicin de aspectos . En este paso se deben definir las reglas de composicin mediante la creacin de mdulos o aspectos . Este proceso, conocido como weaving , utiliza esta informacin para construir el sistema final. La principal aportacin de AOP es la independencia de los "concerns" en el momento de su implementacin. El modo en que se realiza la implementacin permite una completa trazabilidad entre los requerimientos y su implementacin, por lo que el sistema final ser ms fcil de comprender, implementar o adaptar ante futuros cambios

Anatoma de un lenguaje orientado a aspectos


La orientacin a aspectos es simplemente una metodologa por lo que ser necesario definir el lenguaje y ofrecer un conjunto de herramientas para trabajar con la misma. Al igual que otra metodologa de programacin, una implementacin concreta de AOP constar de dos partes: Especificacin del lenguaje encargado de describir las construcciones y sintaxis que sern utilizadas en la construccin y el tejido de todos los "concerns", tanto los pertenecientes al ncleo como los transversales. La implementacin del lenguaje es la encargada de verificar la adherencia del cdigo a la especificacin del lenguaje y de trasladar el cdigo a un ejecutable capaz de ser comprendido por una mquina. Esta tarea,habitualmente,es realizada por un compilador o un intrprete.

Especificacin del lenguaje AOP


Cualquier implementacin de la metodologa AOP requiere la definicin de dos lenguajes: el primero de ellos permitir realizar la implementacin de los requisitos individuales mientras que gracias al segundo podremos definir las reglas que "tejen" el conjunto de mdulos independientes. Implementacin de concerns .Al igual que en otras metodologas, los requisitos se implementan en mdulos que contienen los datos y el comportamiento necesario para ofrecer sus servicios. Imaginemos por ejemplo que estamos construyendo el ncleo del concern de seguridad; dicho ncleo mantendr un manager de control de accesos y una coleccin de elementos ( voters ). Habitualmente,tanto los concerns transversales como los del ncleo se implementan mediante la utilizacin de lenguajes estndar como pueden ser C++ o Java. Especificacin de reglas de "tejido". Las reglas de tejido especifican cmo debemos integrar los diferentes concerns que hemos implementado para componer el sistema final. El lenguaje utilizado para definir estas reglas puede ser una evolucin del lenguaje natural o algo completamente diferente. As por ejemplo, podramos ofrecer una implementacin de la metodologa AOP en la que Java es el lenguaje base y la definicin de reglas de tejido se realiza mediante un DSL implementado en Groovy .

Implementacin de AOP
La implementacin del lenguaje debe llevar a cabo dos acciones:combinar los aspectos individuales mediante las reglas de tejido,para, posteriormente, convertir la informacin resultante en cdigo 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 introduccin de este punto, el proceso de weaving es el encargado de componer el sistema final mediante la composicin de los diferentes concerns siguiendo las pautas establecidas en las reglas de tejido . Estas reglas son definidas en aspectos

Aspect Oriented Programming

independientes del ncleo del sistema por lo que con unas nuevas reglas de "tejido" podramos 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 implementacin sera utilizar una transformacin cdigo a cdigo (un compilador). De ese modo, el compilador de aop "tejera" los aspectos junto al resto de clases generando un nuevo cdigo ya "tejido". Una vez finalizado este proceso, el cdigo generado anteriormente servira como entrada para el compilador de lenguaje base el cual sera el encargado de generar el ejecutable. Utilizando el enfoque anterior, una aproximacin basada en C++ convertira todos los archivos individuales (aspectos y clases) en cdigo C++ tejido(weaving). El siguiente diagrama ilustra la aproximacin descrita en el prrafo anterior:

Figure 1.4. Proceso de generacin del sistema final

Beneficios de la metodologa AOP


La mayora de las crticas 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 tecnologa relativamente nueva. Algunos de los beneficios ms detacables de esta metodologa son: Responsabilidades claramente diferenciadas . Cada mdulo es el responsable de su funcionalidad principal; dejando de lado los conceptos transversales. As por ejemplo, un mdulo cuyo principal cometido es implementar la lgica 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 asignacin de responsabilidades se consigue una alta trazabilidad entre los requisitos y su correspondiente implementacin. Incremento de la modularidad . Utilizando AOP se consigue manejar cada uno de los conceptos de manera independiente con un acoplamiento mnimo. Incluso aunque estn presentes conceptos transversales que afecten al sistema completo, la implementacin es modular. Retraso en las decisiones de diseo .Cuando se arquitecta un nuevo sistema siempre aparece el siguiente dilema: se debe realizar un diseo sumamente complejo y detallado que intente abarcar todas las funcionalidades,incluso las futuras? o, por el contrario, debe arquitectarse una solucin que se corresponda con la situacin actual?. Gracias a AOP, el arquitecto de la solucin, puede retrasar la toma de determinadas decisiones de diseo dado que los futuros requerimientos se implementarn en aspectos independientes. Dando un paso ms adelante, AOP conforma un gran equipo junto con una metodologa gil como puede ser

Aspect Oriented Programming

XP (siglas en ingls de Programacin Extrema) siguiendo la prctica del principio YAGNI (siglas en ingls 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 aadir una nueva funcionalidad sin ms que desarrollar un nuevo aspecto (el cual no afecta al ncleo del sistema). Gracias a ello, el tiempo de respuesta ante nuevos requerimientos disminuye notablemente. Incremento en la reutilizacin del cdigo .Puesto que AOP implementa cada aspecto en un mdulo 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 mdulos son las reglas de tejido , de manera que, si cambiamos stas, podemos componer un sistema final completamente diferente. Reduccin de costes y accesos al mercado ms rpidos .Las caractersticas descritas en los puntos anteriores generan sistemas ms rpidos, tanto en su desarrollo como en su implantacin . Eliminando la necesidad de modificar mltiples mdulos para la implementacin de un nuevo concepto transversal, AOP provoca que dicha implementacin sea ms barata. Asimismo, permitiendo que los desarrolladores estn centrados en su especialidad logramos que el coste del desarrollo disminuya.

Verdades y mentiras sobre AOP


En los ltimos aos AOP ha sufrido un gran crecimiento aunque,en algunas ocasiones, todava se percibe demasiado complicado, tanto en su implementacin como en su proceso de aprendizaje. A continuacin veremos algunas hiptesis y los motivos por los que las mismas son consideradas ciertas o falsas: AOP no soluciona nuevos problemas . Esta afirmacin es completamente cierta. La orientacin a aspectos no ofrece solucin a problemas irresolubles sino que aporta soluciones ms sencillas y elegantes a los problemas actuales. Al fin y al cabo, no hay nada que no podamos implementar con cdigo mquina. Flujos complicados de seguir . De nuevo esta afirmacin es cierta. En muchas ocasiones, en funcin de la complejidad del sistema que estemos construyendo, el orden en el que se ejecutan las instrucciones puede resultar complicado de seguir. La afirmacin anterior tambin es cierta para otras metodologas ajenas a AOP. En OOP, el uso del polimorfismo hace que analizar el flujo de ejecucin de un programa no sea una tarea sencilla. Incluso en lenguajes procedimientales, como podra ser C, el uso de punteros a funciones dificulta las tareas de seguimiento del programa. AOP promueve malos diseos . En esta ocasin la afirmacin es falsa. Una aproximacin orientada a aspectos no es la solucin para un mal diseo sino que simplemente facilita nuevos modos de resolucin de problemas en aquellas reas en las que lenguajes procedimientales u orientados a objetos presentan carencias. Los interfaces de las metodologas OOP son suficientes . De nuevo en esta ocasin, la afirmacin anterior es falsa. La tcnica descrita propone utilizar un interfaz e ir intercambiando las implementaciones subyancentes (ntese que esto no implica cambios en el API). Puede parecer a simple vista que esta solucin es satisfactoria, pero dista mucho de ser as, puesto que necesitamos invocar al cdigo en todos aquellos lugares en los que corresponda. Esta tcnica sirve de gran ayuda (tanto en OOP como AOP), pero en ningn momento los interfaces son una alternativa a la orientacin a aspectos. AOP supone una ruptura de la encapsulacin . Esto afirmacin es cierta aunque con ciertos matices puesto que dicha ruptura se realiza de una manera controlada y sistemtica. 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 seguirn siendo implementados en OOP ( o puede que en un lenguaje procedimantal como puede ser C). AOP aade un nuevo conjunto de conceptos adicionales a la metodologa orientada a objetos. Efectivamente, AOP cambiar el modo en el que se utilizan las metodologas actuales para la implementacin de conceptos transversales.

Visin general de AspectJ


AspectJ es una extensin orientada a aspectos de propsito general al lenguaje Java. Puesto que es una extensin del lenguaje Java, cualquier programa escrito en dicho lenguaje es un programa AspectJ vlido. Un compilador AspectJ genera archivos .class de acuerdo a la especificacin del bytecode de Java de manera que cualquier implementacin de la mquina 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 especificacin 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 implementacin del lenguaje facilita herramientas como compiladores, depuradores e integracin con la mayora de IDEs modernos. Los siguientes apartados servirn de introduccin a AspectJ y algunos conceptos avanzados gracias a los cuales se podr comenzar a escribir programas simples.

Introduccin a AspectJ
El compilador de AspectJ es el encargado de utilizar los mdulos que contienen las definiciones de las reglas de tejido para aadir nuevo comportamiento a los mdulos que implementan las funcionalidades principales. El proceso anterior no realiza ninguna modificacin sobre el cdigo fuente del ncleo 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 trmino) est compuesto de dos partes claramente diferenciadas: los "join point", que no son ms que puntos en la ejecucin de un programa, y los "pointcuts", un mecanismo de seleccin de los puntos anteriores. Imaginemos por un momento que nos encontramos desarrollando un sistema que necesita gestin de la seguridad, algo muy comn en el mundo en el que nos movemos, y, que, debido a la naturaleza transversal del mismo, elegimos AOP como enfoque principal de nuestra solucin. Cules son los pasos que deberamos 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 seleccin de los "joint point" descritos en el punto anterior. 3. Construiremos un aspecto que encapsule toda la lgica de seguridad requerida. Los conceptos anteriores son sumamente importantes dado que componen la base de AOP. Los siguientes subapartados profundizarn en cada uno de ellos.

11

Aspect Oriented Programming

Joint Point
Como ya se defini anteriormente, un join point es un punto de ejecucin en un sistema. As por ejemplo, el acceso al campo de una clase, la ejecucin de una funcin 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 ms estables.

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

Seleccin de joint points


Los pointcut especifican un criterio de seleccin. Utilizaremos tipos, campos, mtodos, anotaciones, etc para generar dichas definiciones. Tambin podremos establecer condiciones en tiempo de ejecucin que tendrn que cumplirse en el joint point seleccionado.

Determinacin del contexto


Los joint point disponen de informacin en tiempo de ejecucin. Determinados pointcuts pueden recolectar dicha informacin y pasrsela al advice. Por ejemplo, la llamada a un mtodo de un objeto tendr disponible el propio objeto que realiza la llamada y los argumentos que se estn pasando.

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

Categoras de joint points


A continuacin se ver un conjunto de categoras de joints points expuestas por AspectJ. A pesar de ser un nmero considerable de categoras, no se han incluido todas, sino aquellas que se utilizan con mayor frecuencia. Si el lector desea realizar una lectura ms profunda aqu podr encontrar todo lo que necesita: AspectJ Programming Guide [http://www.eclipse.org/aspectj/docs.php]

Table 1.1. Categoras de joint points expuestas por AspectJ (resumen)


Categora Mtodo Mtodo Constructor Constructor Acceso a un campo Acceso a un campo Inicializacin Inicializacin Inicializacin Advice Joint Point Expuesto Execution Call Execution Call Read Write Class init Object init Object pre-init Execution Cdigo que representa Cuerpo del mtodo Invocacin del mtodo Ejecucin de la lgica de creacin de un objeto Invocacin de la lgica de creacin de un objeto Lectura de un objeto o el campo de una clase Escritura de un objeto o el campo de una clase Bloque catch para manejar una excepcin Proceso de carga de una clase (class loading) Inicializacin de un objeto en un constructor Pre-inicializacin de un objeto en un constructor Ejecucin de un advice

Proceso de excepciones Handler

12

Aspect Oriented Programming

Conceptos bsicos
A continuacin se analizarn los elementos bsicos que se deben conocer para definir un pointcut.

Pointcuts annimos o con nombre


Se permite la declaracin de pointcuts de cualquiera de los dos tipos. Los primeros son similares a las clases annimas, y por tanto se definen en el lugar en el que se van a utilizar. En el caso de los segundos, podremos referenciarlos desde mltiples lugares, permitiendo de este modo su reutilizacin.

Operadores
AspectJ proporciona el operador unario de negacin (!) y dos operadores binarios: && y ||, gracias a los cuales se permite construir reglas de matching complejas mediante la combinacin de pointcuts ms sencillos. Tanto la semntica como la precedencia es la misma que en el lenguaje Java. As por ejemplo,en el caso del operador binario &&, se seleccionarn aquellos joint points que concuerden con los dos pointcuts que actan como operandos.

Signaturas: sintaxis y ejemplos


Las signaturas son la base de la definicin de los pointcuts. El lenguaje debe facilitar una manera sencilla que permita definir criterios de seleccin sobre los diferentes aspectos transversales que estamos implementando. En el caso de AspectJ, se utilizan expresiones regulares (wildcards) en combinacin a las signaturas. Los siguientes wildcards son soportados: * especifica cualquier nmero 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 mtodos o campos) .. determina cualquier nmero de caractres, incluyendo en este caso cualquier nmero de puntos (.). En la signatura de un tipo representa cualquier paquete o subpaquete. En la signatura de un mtodo representa cualquier nmero de argumentos. + denota cualquier subtipo de un tipo determinado. A lo largo de los siguientes subapartados veremos, a travs 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


Patrn de signatura AstVisitor *AstVisitor la Descripcin El tipo AstVisitor Ejemplos de tipos concordantes Slo el tipo AstVisitor concuerda (ni tipos base ni derivados)

Cualquier tipo cuyo nombre termine en Por ejemplo, HighlightingAstVisitor o AstVisitor SemanticAstVisitor concuerdan con el patrn El tipo Date en cualquier subpaquete java.util.Date o java.sql.Date son directo del paquete java ejemplos de tipos concordantes 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

java.*.Date javax..*

13

Aspect Oriented Programming

Patrn de signatura javax..*Model

la Descripcin

Ejemplos de tipos concordantes

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


Patrn de signatura @Secured User @Entity * @Transactional* Manager+ la Descripcin Ejemplos de tipos concorndantes

El tipo User anotado con la anotacin @Secured class User{. . .} Secured Cualquier tipo anotado con la anotacin @Entity class Section {. . .},@Entity Entity class Report {. . .} El tipo Manager y cualquiera de sus clases derivadas que estn anotados con una anotacin cuyo nombre comienze por Transactional @TransactionalDefault class Manager{},@TransactionalOracle class OracleManager extends Manager{}

Signaturas de tipos: generics Table 1.4. Ejemplos de signaturas de tipos: generics


Patrn de signatura la Descripcin Ejemplos de tipos concordantes

Map <Integer,String> *<User> Collection<? extends User> Collection<? super User>

El tipo Map cuyo primer argumento En este caso nicamente concordar el genrico est fijado a Integer y el tipo Map<Integer,String> segundo a String Cualquier tipo genrico cuyo nico Collection<User>,List<User>, . . . argumento genrico sea de tipo User El tipo Collection con un parmetro de Collection<User>, tipo User o derivado Collection<DomainUser>, . . . El tipo Collection, cuyo parmetro ser Collection<Serializable>, 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


Patrn de signatura !Collection Set || Map !@Transactional @Serializable @Encrypted * la Descripcin Cualquier tipo excepto Collection Los tipos Set o Map Ejemplos de tipos concordantes User,Model, List (aunque sea subclase de Collection) Los tipos Set y Map nicamente

Cualquier tipo que se encuentre anotado class NonTransactionalManager{} por por la anotacin Transactional Cualquier tipo que se encuentre anotado @Serializable @Encrypted por las dos anotaciones UserCredentials{} class

14

Aspect Oriented Programming

Patrn de signatura

la Descripcin

Ejemplos de tipos concordantes

(@Serializable || Cualquier tipo que est anotado por @Serializable class User {} @Encrypted) * alguna de las dos anotaciones

Signaturas de mtodos y constructores Table 1.6. Signaturas de mtodos


Patrn de signatura la Descripcin Ejemplos de mtodos concordantes

public void Cualquier mtodo pblico 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 User.*() void Cualquier mtodo pblico de la clase class User { public void updateInfo() User cuyo tipo de retorno sea void y que {}} no espere argumentos Cualquier mtodo pblico de la clase class User{ public User que no espera argumentos y getUserInfo(){}} retorna cualquier tipo UserInfo

public * User.*()

public * User.*(..) Cualquier mtodo pblico de la clase User que retorna cualquier tipo, y espera cualquier nmero y tipo de argumentos (incluido cero) * *.*(..) o * * (..)

class User{ public UserInfo getUserInfo(){},public Date updatesBetween(Date first,Date last) {}}

Cualquier mtodo independiente de su Cualquier mtodo del sistema tipo, del tipo de retorno, de su nombre y de los argumentos que espere

!public * User.*(..) Cualquier mtodo que no sea pblico class User {protected getUserInfo(){}} (privado,protegido o paquete) * * (..) throws Cualquier mtodo que declare que clas AntlRBasedParser { RecognitionException puede lanzar una excepcin de tipo void parser(String file) RecognitionException RecognitionException} * User+.*(..) User UserService.*(..) public throws

Cualquier mtodo en la clase User y sus class UserDetails extends User {} subclases Cualquier mtodo del tipo UserService cuyo tipo de retorno sea User. Si alguna de las subclases sobreescribe el tipo de retorno con un subtipo de User (mediante el tipo de retorno covariante introducido en Java 5) tambin ser seleccionado. class UserService{public User retrieveUser(String name){}} class DetailUserService extends UserService{public DetailedUser retrieveUser(String name){}}

La signatura en el caso de los constructores difiere de la signatura de mtodos en los siguientes aspectos: Los constructores no tienen tipo de retorno por lo que no se permite utilizar el valor de retorno en la especificacin 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 estticos, no se podr utilizar la palabra reservada static

15

Aspect Oriented Programming

Signaturas de campos Table 1.7. Signaturas de campos de clase


Patrn de signatura la Descripcin Ejemplos de campos concordantes

private String Campo privado (tanto campo de una class User { private String username;} User.username instancia como esttico) 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;} 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.

* User+.*

Implementacin de pointcuts
AspectJ ofrece dos mecanimos diferentes que permiten a los pointcuts realizar la seleccin de los joint points Kinded pointcuts. En este caso, los pointcuts seleccionan categoras de joint points (de ah su nombre). As, por ejemplo, se ofrece la posibilidad de realizar matching sobre la ejecucin de un mtodo Non-kinded pointcuts. Se seleccionan los joint point en base a la informacin de la que disponen, como los tipos en tiempo de ejecucin o su contexto. En esta situacin se seleccionan joint points de cualquier clase, siempre y cuando sastisfagan la condicin 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


Categora de Joint Point Ejecucin de un mtodo Llamada a un mtodo Ejecucin de un constructor Llamada a un constructor Inicalizacin de una clase Acceso de lectura a un campo Acceso de escritura a un campo Ejecucin de un manejador de excepciones Inicializacin de un objeto Pre-inicializacin de un objeto Ejecucin de un advice Sintaxis del pointcut execution(MethodSignature) call(MethodSignature) execution(ConstructorSignature) call(ConstructorSignature) staticinitializaction(TypeSignature) get(FieldSignature) set(FieldSignature) handler(TypeSignature) initialization(ConstructorSignature) preinitialization(ConstructorSignature) adviceexecution()

Por ejemplo, si deseamos seleccionar todas las llamadas a los mtodos pblicos commit() de la clase TransactionManager, escribiramos un pointcut similar al siguiente: call(public void TransactionManager.commit(. .))

16

Aspect Oriented Programming

Non-kinded pointcuts
Este tipo de pointctus permiten la seleccin 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 incluira las llamadas a mtodos, ejecuciones, manejadores de excepciones, etc. De nuevo, a travs 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 cflow(execution(* TransactionManager.commit())) cflowbellow(execution(* TransactionManager.commit())) Descripcin Selecciona todos los joint points en el flujo de la ejecucin de cualquier operacin commit de la clase TransactionManager, incluyendo la ejecucin del propio mtodo. Selecciona todos los joint points en el flujo de la ejecucin de cualquier operacin commit de la clase TransactionManager, excluyendo la ejecucin del mtodo.

cflow(execution(@Secured * * Todos los joint points en el flujo de la ejecucin de cualquier (..))) mtodo anotado con la anotacin Secured cflow(transacted()) Cualquier joint point en el flujo de ejecucin de los joint points seleccionados por el pointcut transacted()

Non-kinded pointcuts basados en la estructura lxica Dentro de este tipo de pointcuts tenemos dos categoras: 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 mtodo o un constructor, incluendo la definicin de cualquier clase local que puediera aparecer en los mismos.

Table 1.10. Non-kinded pointcuts basados en la estructura lxica


Pointcut within(User) within(User+) within(@Transactional *) Descripcin Selecciona todos los joint points que aparecen dentro de la clase User Selecciona todos los joint points que aparecen dentro de la clase user y cualquiera de sus clases derivadas Selecciona todos los joint points que aparecen dentro de cualquier clase que se encuentre marcada con la notacin Transactional

withincode(* Selecciona todos los joint points que parecen dentro de cualquier TransactionManager.retrieve*(..)) mtodo de la clase TransactionManager cuyo nombre comience por retrieve Non-kinded pointcuts de ejecucin Este tipo de pointcuts nos permiten seleccionar joint points en base al tipo de los objetos en tiempo de ejecucin. 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 ejecucin


Pointcut this(User) Descripcin Selecciona cualquier joint point en que se la expressin this instanceof User sea cierta. As por ejemplo, seleccionar las llamadas a mtodos o accesos a campos donde el objeto actual sea de tipo User o cualquier de sus subclases. Selecciona cualquier joint point en el que el objeto sobre el que se realiza la llamada al mtodo es instanceof User

target(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 ejecucin. Veamos los distintos tipos de argumentos, en funcin del tipo del joint point : En el caso de los joint points manejadores de excepciones el argumento ser la excepcin manejada. En los mtodos y constructores, los argumentos sern los argumentos del mtodo y constructor Los accesos de modificacin 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 Descripcin args(User, . . , Selecciona cualquier joint point de tipo mtodo 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. Seleccionara cualquier mtodo 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 tambin seleccinara un manejador de excepciones de tipo SqlException Non-kinded pointcuts condicionales Este tipo de pointcuts nos permiten seleccionar joint points basados en una expresin condicional

Table 1.13. Ejemplos de pointcuts condicionales


Pointcut if(debug) Descripcin Selecciona cualquier joint point donde el campo esttico debug (en la definicin del aspecto) toma el valor cierto

Crosscutting dinmico
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 inters. Durante este captulo analizaremos el modo en el que podemos alterar el comportamiento de nuestro sistema en los joint points que hayamos seleccionado mediante la definicin de nuestros pointcuts.

Descripcin general
Las reglas de tejido estn compuestas de dos partes:
3

El trmino crosscuting representa la naturaleza transversal de las funcionalidades que estamos aadiendo. Se ha optado por no realizar la traduccin del trmino y utilizar la terminologa orginal

18

Aspect Oriented Programming

advice: qu deseamos hacer pointcuts: donde aplicamos el advice anterior AspectJ soporta el crosscutting dinmico mediante los advices, construcciones similares a los mtodos que nos permiten definir las acciones que a ejecutar en los joint points seleccionados por un pointcut.

Categoras de advices
Dependiendo de las funcionalidades que estemos implementando necesitaremos ejecutar nuestra lgica en un determinado lugar del flujo de ejcucin orginal; as por ejemplo, si estamos construyendo la seguridad de un sistema, nuestro cdigo tendr que verificar dicha seguridad antes de la ejecucin del joint point. Si estuvieramos construyendo un sistema de cachs, nuestra nueva funcionalidad tendra que ejecutarse alrededor de joint point original, intentando recuperar el valor de la cach, y en caso de que no exista, ejecutar el cdigo real y aadirlo a la misma para futuras invocaciones. AspectJ ofrece tres categorias de advices que satisfacen los escenarios anteriores (y alguno ms): Before Advice se ejecutan anteriormente a la ejecucin del joint point After Advice: se ejecutan posteriormente a la ejecucin del joint point. Existen tres variantes diferentes After finally se ejecuta tras la ejecucin del join point independientemente del resultado de dicha ejecucin After returning se ejecuta tras la ejecucin del joint point siempre y cundo sta ltima haya finalizado correctamente, es decir, sin lanzar ninguna excepcin. After throwing se ejecuta tras la ejecucin fallida de un joint point, es decir, despus de que dicho joint point dispare una excepcin. Around Advice rodean la ejecucin del joint point.

Sintaxis de los advices


Aunque la sintaxis vara ligeramente dependiendo del tipo de advice que estemos escribiendo, podramos dividir su estructura general en tres partes claramente diferenciadas: Declaracin del advice. En esta parte de la declaracin se especifica el momento de ejecucin del advice, es decir, si se ejecutar antes, despus y alrededor de los joint points Definicin de los pointcuts. Se especifican los pointcuts sobre los que se desea actuar. Cuerpo del advice. Definicin del cdigo a ejecutar una vez se haya alcanzado el joint point indicado. Veamos un ejemplo sencillo de definicin 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 mtodo de la clase User, y, adicionalmente estamos recogiendo el objeto que actua como target de la llamada. A continuacin 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 definicin anterior podemos ver la estructura de la declaracin de un advice descrita anteriormente 1. La parte que precede a los dos puntos indica el momento de ejecucin 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 definicin de los criterios que determinan cuando se ejecutar el advice 3. La ltima parte representa el cuerpo del advice, es decir, el cdigo que se ejecutar cuando alguno de los joint point definidos por el pointcut sea alcanzado.

Advices y mtodos
Al igual que los mtodos de una clase, los advices se utilizan para definir comportamiento. La sintaxis de stos ltimos es similar a la de los mtodos aunque existen algunas diferencias dado que los advices son aplicados de manera automtica, sin la necesidad de realizar explicitamente la invocacin del mismo.

Similitudes
Analizemos las similitudes de ambos en tres categoras diferentes: declaracin, cuerpo y comportamiento. La declaracin de un advice es similar a la signatura de un mtodo tradicional: Opcionalmente puede asigarse un nombre al advice mediante el uso de la anotacin @AdviceName Recibe argumentos a travs del contexto del joint point, que posteriormente podrn ser utilizados en el cuerpo para implementar la lgica necesaria. Puede declarar el lanzamiento de una excepcin. En cuerpo de los advices tambin es muy parecido al de los mtodos: El cdigo 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 implementacin podra disparar. En el caso de los mtodos, los advices : No pueden declarar el disparo de una excepcin 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 ms especficas (de tipo checked) que las definidas por los joint point sobre los que est actuando. Pueden lanzar cualquier tipo de excepcin de tipo runtime.

20

Aspect Oriented Programming

Diferencias
En comparacin con los mtodos, los advices: La declaracin de un nombre es opcional. No pueden ser invocados directamente. No presentan especificadores de acceso (relacionado con la caracterstica 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 thisJointPoint,thisJointPointStaticPart,thisEnclosingJointPointStaticPart propio aspecto:

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.

Anlisis detallado de los advices


Hasta este momento disponemos de la informacin sobre las diferentes categoras de advices y su sintxis 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 ejecucin del joint point sobre el que actan. En el siguiente ejemplo: before():execution(@Secured * * (..)){ // asegurarse de que el usuario puede realizar la operacin } el advice realiza una comprobacin de seguridad antes de que se produzca la ejecucin de cualquier mtodo anotado con Secured. En caso de que el advice dispare una excepcin, el joint point no se ejecutar. Este tipo de aspectos son comunmente utilizados en aspectos tales como seguridad o trazabilidad.

After advice
Se ejecutan despus de la ejecucin del joint point sobre el que actuan. Dentro de esta categora, AspectJ ofrece tres tipos de advices: Ejecucin del advice independientemente del resultado de la ejecucin del joint point. Ejecucin del advice nica y exclusivamente si el joint point ha finalizado correctamente. Ejecucin del advice despus que el joint point haya disparado una excepcin. Veamos en detalle cada uno de los tres tipos anteriores: Advice After Este tipo de advices se ejecutan independientemente del resultado de la ejecucin del joint point sobre el que actan. Habitualmente se conoce a este tipo de advices como after finally puesto que su semntica es similar a la de un bloque finally. El siguiente advice: after(): call(@Logging * ServiceManager.*(..)){ // registrar el resultado de la operacin

21

Aspect Oriented Programming

} registra el resultado de todas las operaciones de la clase ServiceManager que estn marcadas con la anotacin Loggin, independientemente si retornan correctamente o terminan su ejecucin de forma inesperada mediante el disparo de una excepcin. Advice After Returning En muchas ocasiones,ser necesario ejecutar el cdigo de nuestro advice nica y exclusivamente cuando la ejecucin del joint point haya terminado de forma correcta. Continuando con el ejemplo anterior: after () returning: call(@Logging * ServiceManager.*(..)){ // registrar el resultado de la operacin } se seguir registrando el resultado de las operaciones, siempre y cuando, la ejecucin haya terminado correctamente, sin el disparo de ninguna excepcin. AspectJ ofrece una pequea variante para este tipo de advices:

after() returning (ReturnType returnObject) gracias a la cual se permite recuperar el objeto retornado por la ejecucin del joint point dentro del advice. Veamos un pequeo ejemplo ilustrativo:

after() returning (java.sql.Connection connection): call(java.sql.Connection DriverManager.getConnection(..)){ System.out.println("Se ha recuperado la conexin " + 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 excepcin. Presentan la siguiente estructura: after() throwing:execution (* ServiceManager+.*(..)) El advice del ejemplo anterior se ejecutar siempre y cuando algn mtodo de la clase ServiceManager (o alguna de sus subclases), dispare una excepcin. En el supuesto de que la ejecucin del joint point termine correctamente, este tipo de advices no sern ejecutados. Al igual que los advices del apartado anterior, AspectJ ofrece una modo de recuperar la excepcin que ha sido disparada por el joint point de modo que est disponible en el cuerpo del advice. Siguiendo una sintxis similar a la anterior, tendramos: after() throwing (ExceptionType exceptionObject): Un after throwing advice nunca podr tragarse la excepcin;por lo que seguir subiendo por la pila de llamadas hasta llegar al objeto que realiz la invocacin del joint point.

Around advice
Este clase de advices engloban al joint point, pudiendo ejecutar la lgica del mismo un nmero indefinido de veces. Incluso pueden omitir la ejecucin del propio joint point. Algunos de los usos principales de este tipo de advices son los siguientes:

22

Aspect Oriented Programming

Ejecucin de lgica adicional antes y despus de la ejecucin de un joint point, como por ejemplo, acciones de profiling. Omitir la ejecucin original, y realizar otra en su lugar, como por ejemplo, operaciones con cachs. Envolver la operacin con una gestin de excepciones, con el objetivo de aplicar una poltica de gestin de excepciones. Un ejemplo de este uso sera la gestin de transacciones. Este advice ofrece una potencia superior a todos los advices vistos hasta el momento, puesto que podran sustituir a los anteriores. De todos modos, se considera una buena prctica utilizar el advice ms sencillo que cumpla las necesidades de la tarea que necesitamos llevar a cabo. Ejecucin del joint point Si desde el around advice deseamos llevar a cabo la ejecucin del joint point, tendremos que hacer uso de la palabra reservada proceed() dentro del cuerpo del advice. Debemos recordar, que, puesto que la invocacin de proceed() ejecuta el joint point, tendremos que pasarle el mismo nmero de argumentos que han sido recolectados por el advice. Asimismo, puesto que la invocacin de proceed() supone la ejecucin del joint point, el valor de retorno ser el retornado por ste ltimo. Veamos un pequeo ejemplo de utilizacin 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 construccin anterior: 1. El pointcut selecciona cualquier llamada a los mtodos de la clase User cuyo nombre comienze por pay y disparen una excepcin 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 nmero de crditos que se estn pasando como argumento del mtodo que se est ejecutando. 3. En el cuerpo del advice, se engloba la ejecucin del mtodo con un bloque de gestin de excepciones, para realizar una proteccin adicional en caso de que se produzca una excepcin. En el caso de que la proteccin adicional no sea correcta, la excepcin 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 aadiendo 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 caracterstica es similar a la incluida a partir de Java 5, pero AspectJ no precisa de dicha versin de Java para realizar la operacin.

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 ejecucin del joint point para que el advice pueda llevar a cabo la lgica correspondiente. Por tanto, los pointcuts, necesitan exponer el contexto disponible en la ejecucin 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 this(obj) target(obj) Contexto recuperado Objecto this en el joint point que se est ejecutando Objetivo de la llamada en el joint point que se est ejecutando. En el caso de un joint point de una llamada a un mtodo, el target ser el objeto que realiza la llamada. Para la ejecucin de un mtodo, 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 Objetos que representa los argumentos en el joint point. Para las llamadas/ ejecuciones de mtodos/constructores, recupera los argumentos de los mismo. En el caso de los manejadores de excepciones, recupera la excepcin producida. Para los accesos en modo escritura a un campo, recupera el nuevo valor del campo. Anotacin asociada con el tipo del objeto this del joint point Anotacin asociada con el tipo del objeto target del joint point Anotacin asociada con el tipo "enclosing" del joint point Anotacin asociada con el mtodo "enclosing" del joint point Anotacin asociada con el asunto actual del joint point.

args(obj1,obj2,...)

@this(annot) @target(annot) @within(annot) @withincode(annot) annotation(annot)

@args(annot1,annot2,...)Anotacin asociada con el tipo de los argumentos del joint point

Aspectos
Los aspectos representan la nidad bsica de modularizacin en el mundo de la orientacin a aspectos en general, y en AspectJ, en particular. Los siguientes subapartados nos mostrarn una definicin ms 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 implementacin de todos los conceptos transversales. Ser el weaver el encargado de modificar el comportamiento del ncleo del sistema en funcin de la informacin 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 declaracin de un nuevo aspecto. Cada uno de estos aspectos presenta las siguientes caractersticas: Presenta un nombre para podere referirse a l desde otras partes del cdigo. 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 instanciacin 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 prcticamente lo mismo, pero no es as, los aspectos no son clases. A continuacin se describen algunas de las diferencias principales: Modelo de instanciacin Es el sistema el encargado de la instanciacin 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, slo pueden derivar de aspectos definidos como abstract. Esto es una restriccin que se incluy en la definicin del lenguaje para evitar complejidades innecesarias. Parmetros genricos Los aspectos concretos no pueden declarar parmetros genricos, slo aquellos marcados como abstract podran hacerlo. El motivo es el modelo de instanciacin, 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 cul 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 evolucin 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 travs del cual el lector pueda comprender los beneficios de esta tecnologa y le permita utilizarlo para escribir sus propios programas. Soy consciente de que se han quedado muchas cosas en el tintero, que daran cabida para un libro completo, por lo que a continuacin se enumeran algunas de ellas para las mentes inquietas que deseen profundizar en otros aspectos que no tienen cabida en este documento: Tcnicas como static crosscutting tales como: Introduccin de nuevos miembros en una clase Complemento de anotaciones Modificacin de jerarquas de tipos Respuesta a errores y warnings en tiempo de compilacin Debilitado de excepciones Asociacin y predencia de aspectos Sintxis @AspectJ Anlisis detallado de los procesos de weaving Integracin con Spring ... Para una anlisis exhaustivo de estos y otros muchos aspectos, el usuario puede acudir a la seccin bibliografa El objetivo de este introduccin no era dar una visin terica y aburrida de AspectJ sino dar una visin pragmtica del mismo. De este modo, la siguiente seccin ilustrar la mayora 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 exploracin de sus elementos, sintxis y ejemplos sencillos. Los siguientes subapartados ofrecern un conjunto de ejemplos reales de aplicacin de la tecnologa as como algunos patrones habituales. La estructura de los ejemplos ser la siguiente: se plantear un problema, se dar una solucin general, y despus se propondr una alternativa basada en AOP y AspectJ. Pongmonos manos a la obra.

Patrn wormhole

Este patrn consiste, bsicamente, en habilitar un contexto de informacin desde un llamante a un llamado sin la necesidad de pasar dicha informacin como un conjunto de argumentos a lo largo de todas las invocaciones del los diferentes mtodos del flujo de ejecucin. Imaginemos por un momento que estamos implementando un sistema de seguridad en el que cada uno de los mtodos tiene que comprobar quien les ha invocado para determinar si se les permite ejecutar la operacin. Creando un canal de comunicacin directa entre dos niveles cualesquiera en la pila de llamadas, nos evitar tener que ir moviendo la informacin necesaria por cada una de las capas. De este modo, evitaremos la necesidad de modificar la cadena de llamadas cuando necesitemos aadir algn parmetro adicional al contexto de informacin.
5

De nuevo, se ha optado por mantener la nomenclartura original del patrn, sin realizar una traduccin al castellano, puesto que considero que el resultado de dicha traduccin no resultara demasiado intuitiva para el lector.

26

Aspect Oriented Programming

Solucin tradicional
Sin la utilizacin de una tecnologa como AOP disponemos de dos alternativas de solucin. La primera de ellas movera toda la informacin necesaria a lo largo del contexto de llamadas aadiendo los parmetros que fueran necesarios, mientras que la segunda, hara uso de un almacenamiento espefco de los hilos. La solucin que pasa a travs de parmetros el contexto de informacin necesario produce una contaminacin del API, puesto que cada uno de los mtodos que intervienen en el flujo que transcurre desde el llamante hasta el llamado necesitar de parmetros adicionales que permitan mover dicha informacin a lo largo de la pila de llamadas. La segunda solucin propuesta, el uso de un almacenamiento especfico, pasara porque el llamante crease una variable ThreadLocal en la que se almacenase toda la informacin necesaria. Aunque esta segunda solucin evita la contaminacin del API, se necesita modicar tanto el llamante como el llamado, adems de requerir un conocimiento de cmo se almacena el contexto de informacin.

Descripcin general
La siguiente figura ilustra la idea bsica de este patrn arquitectnico:

Figure 1.5. Diagrama arquitectnico del patrn 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 informacin 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 tendramos que ir pasando toda la informacin de nivel en nivel, hasta que alcanzsemos el nivel deseado. El patrn descrito en esta seccin establece un canal de comunicacin directo a lo largo de todos los niveles de llamadas, evitando el paso de informacin nivel a nivel.

Plantilla
A continuacin se propone una plantilla de solucin que puede ser utilizada como base para la implementacin de este patrn 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 ejecucin de aquellos joint points capturados por el pointcut callerSpace. Puede que con un ejemplo nos queden las cosas un poquito ms claras. Escribamos un pequeo aspecto que genere un canal de comunicacin 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 ejecucin en de la clase TransactionSystem. Adems recolecta el objeto en si en el contexto de ejecucin. El pointcut queryExecutions() captura todas las llamadas a los mtodos exec de la clase SqlQuery y recolecta la propia query y los argumentos El pointcut wormhole genera un canal de comunicacin directo entre el el sistema de transacciones y la ejecucin de la query, capturando todos los joint points que se produzcan bajo el flujo de ejecucin de transactionSystemUsage. Adems, se captura el contexto de los dos pointcuts constituyentes. El advice que actua sobre el pointcut wormhole dispone ahora de toda la informacin: la query y sus parmetros as como el sistema de trasancciones

28

Aspect Oriented Programming

Hilos seguros
La amplia difusin de los procesadores con mltiples ncleos, 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 autntico 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 mdulos. Estas circunstancias pueden ocasionar, la construccin de sistemas no demasiado ricos, con erros aparentes, cadas del sistema inesperadas, integridad comprometid, deadlocks, . . . Por norma general, la implementacin de un sistema de concurrencia basado en los patrones arquitectnicos y de diseo apropiados suele ocasionar sistemas mucho ms fiables que los descritos en el prrafo anterior. Muchos de los patrones de concurrencia presentan numerosos conceptos trasnversales, por lo que AOP puede ayudarnos a simplificar su diseo y posterior implementacin. En este ejemplo, analizaremos el patrn read-write lock. La implentacin clsica de este patrn supone la adicin de cdigo en todos aquellos mtodos que necesiten modificar el estado de un objeto. Los siguientes subapartados nos mostarn como podemos realizar una implementacin modular de este patrn basado en AspectJ.

Implementacin tradicional.
Este patrn utiliza un par de bloqueos (locks): el bloqueo de lectura, y el bloqueo de escritura. Mltiples hilos lectores podrn 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 posesin del bloqueo de escritura. La siguiente clase ilustra, mediante una pequea clase de ejemplo, la solucin 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 operacin, en este caso, // aumentar el crdito 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 operacin, en este caso, // disminuir el crdito 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 mtodos para los que en los que se desee gestionar la gestin de la concurrencia, tendremos que aadir los fragmentos de cdigo vistos en el ejemplo. Cualquier mtodo en el que nos olvidemos de aadir el cdigo de gesti de la concurrencia puede ocasionarnos un incorrecto funcionamiento de nuestro sistema. Adems, debemos asegurarnos que si un mtodo adquire el bloqueo de lectura, sea este el que libere, y no el de lectura, y viceversa.

Implementacin basada en AspectJ


Esta alternativa de solucin propone a creacin de un aspecto que encapule toda la lgica del patrn descrito; evitando de este modo la modificacin de todas aquellas clases que necesiten hacer uso de diho patrn. Puesto que adems, el patrn es reutilizable en numerosas situaciones, haremos que el aspecto tambin lo sea. La base de la solucin, tal y como se indicaba anteriormente, consiste en disponer de un aspecto abstracto que implemente toda la lgica del patrn:

public abstract aspect ReadWriteLockSynchronizationAspect perthis(readOperations() || writeOperations()) {

30

Aspect Oriented Programming

public abstract pointcut readOperation(); public abstract pointcut writeOperation(); private ReadWriteLock lock = new ReentrantReadWriteLock(); Object around(): readOperation(){ this.lock.readLock().lock(); try{ return proceed(); }finally{ this.lock.readLock.unlock(); } } Object around(): writeOperation(){ this.lock.writeLock().lock(); try{ return proceed(); }finally{ this.lock.writeLock.unlock(); } } }

Analicemos con un poquito ms de detalle la definicin del aspecto anterior: 1. En primer lugar, mediante la asociacin de aspectos6, asociamos una instancia de nuestro aspecto con cada uno de los objetos que concuerden con los criterios establecidos en los pointcuts readOperations y writeOperations. Ntese que una nueva instancia de nuestro aspecto ser creada cada vez que se prduzca un matching. El uso de la asociacin nos permite introducir, en las clases que requieren sincronismo, el objeto de lock, sin necesidad de conocer el tipo de las mismas. 2. El pointut abstracto obligar que los aspectos hijos lo tengan que definir, capturando con l todas las llamadas a los mtodos que necesitan sincronismo y no modifican el estado del objeto. 3. De modo similar al anterior, el pointcut writeOperations, capturar todas las llamadas a los mtodos que necesiten realizar una modificacin en el objeto. 4. Puesto que cada matching que se produzca generar una nueva instancia del aspecto para cada objeto this diferente, cada elemento de sinronizacin estar asociado con el objeto sobre el que se est realizando el advice. 5. El around advice readOperation adquiere y libera el bloqueo de lectura. 6. Del mismo modo, writeOperation, adquiere y lbera el bloque de escritura. Ahora que tenemos preprada nuestros aspecto base, realizemos una implementacin concreta. Implementacin de subaspectos La habilitacin de este patrn requiere la implementacin de un aspeto concreto que ponga en juego las clases sobre las que deseamos establecer un control de la concurrencia. Dado que los aspectos concretos tendrn que marcar qu metodos son de lectura y escritura, el uso de anotaciones que nos simplifiquen la seleccin suele ser una buena idea. Por tanto, defininiremos la siguiente anotacin para marcar los mtodos de lectura:

31

Aspect Oriented Programming

@Target(ElementType.METHOD) public @interface ReadOnly{ } Del mismo modo definiremos una anotacin para marcar los mtodos de escritura: @Target(ElementType.METHOD) public @interface ReadWrite{ } Adems, necesitamos definir una anotacin que nos indique cuando estamos utilizando el patrn. @Target(ElementType.TYPE) @Inherited public @interface ReadWriteLockManaged Ahora estamos listos para definir el aspecto,basado en las anotaciones anteriores, que nos aplique el patrn read-write lock. public aspect AnnotationDrivenReadWriteAspect extends ReadWriteLockAspect { public pointcut readWriteLockManaged(): execution(* (@ReadWriteLockManaged *).*(..) ); public pointcut readOperation() : execution(@ReadOnly * *(..)) && readWriteLockManaged(); public pointcut writeOperation() : execution(@ReadWrite * *(..)) && readWriteLockManaged(); }

Analicemos en detalle la construccin del aspecto anterior: 1. El pointcut readWriteLockManaged captura todas las llamadas a los mtodos de aquellas clases que se encuentren marcadas con la anotacin AnnotationDrivenReadWriteAspect 2. El pointcut readOperation complementa al anterior, seleccionando nicamente, de todos los mtodos capturados por readWriteLockManager, aquellos que se encuentren anotados con ReadOnly 3. De un modo similar al anterior, el pointcut writeOperation, captura nicamente aquellos mtodos descritos con la anotacin ReadWrite. Ahora llega la parte ms divertida de esta seccin. Apliquemos nuestra nueva construccin sobre el ejemplo analizado en implementacin tradicional: // package definition . . . import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author migue *

32

Aspect Oriented Programming

*/ @ReadWriteLockManaged public abstract class User { protected String username; protected String login; protected int credits; public User(int credits) { this.credits = credits; } @ReadWrite public void increaseCredit(int credit) { this.credits += credit; } @ReadWrite public void decreaseCredit(int credit) { this.credits -= credit; } @ReadOnly public boolean hasCredit() { return this.credits > 0 ? true : false; } } Comparemos este listado con la implementacin tradicional realizada anteriormente . No resulta mucho ms comprensible? Evidentemente, aunque esta es una buena solucin, existe un acoplamiento entre la anotacin @ReadWriteLockManaged, que una clase indique su participacin en el patrn puede no ser deseable, si dicha clase se utiliza en mltiples sistemas. El problema anterior podra solucionarse mediante la inclusin de un aspecto que introdujese la anotacin en los tipos indicados.7 Veamos un aspecto que introducira la anotacin indicada en las clases que la requieran, de este modo evitaremos el acoplamiento entre la clase y la anotacin que aplica el patrn.

public aspect InventoryReadWriteLockParticipation { declare @type: User: @ReadWriteLockManaged; } El aspecto anterior anotara la clase User con la anotacin ReadWriteLockManaged. De este modo, la anotacin de cualquier clase no requerira ms que la modificacin de este aspecto, para que detectase aquellas clases susceptibles de estar bajo la gestin de concurrencia.

Bibliografa
Al igual que en el resto de captulos, se incluye una referencia bibliogrfica especfica que permitir al lector profundizar en la temtica introducida: AspectJ Programming Guide [http://www.eclipse.org/aspectj/docs.php] AspectJ in Action
7

Aunque no hemos visto la introduccin de tipos, se ha decidido incluir un pequeo aspecto de ejemplo.

33

Aspect Oriented Programming

AspectJ in Action Second Edition: Enterprise AOP with Spring Applications Spring AOP reference [http://static.springsource.org/spring/docs/2.0.8/reference/aop.html] Eclipse AspectJ. Aspect-Oriented Programming with AspectJ and the Eclipse Aspect - Addison Wesley - 2004 John Wiley And Sons Mastering Aspectj Aspect-Oriented Programming in Java AspectJ.Cookbook - OReilly - 2004 Mastering AspectJ - Wiley

34

Você também pode gostar