LENGUAJES DE PROGRAMACIÓN.

Los LOA son aquellos lenguajes que permiten separar la definición de la funcionalidad “principal” de la definición de los diferentes aspectos. Los LOA deben satisfacer varias propiedades deseables:

Los LOA distinguen dos enfoques diferentes en el diseño de los lenguajes orientados a aspectos: los lenguajes orientados a aspectos de dominio específico y los lenguajes orientados a aspectos de propósito general.

Los LOA de dominio específico han sido diseñados para soportar algún tipo particular de aspectos, como por ejemplo la concurrencia, sincronización o distribución. Este tipo de lenguajes suelen tener un nivel de abstracción mayor que el lenguaje base y permiten representar los conceptos específicos del aspecto a un nivel de representación más elevado.

Algunos de estos lenguajes necesitan imponer restricciones en el lenguaje base, para garantizar que las incumbencias que son tratadas en los aspectos no puedan ser programadas en los componentes, evitando de esta manera inconsistencias o funcionamientos no deseados. Por ejemplo, si el lenguaje de aspectos se especializa en la concurrencia o sincronización, puede requerir que sean deshabilitadas las primitivas del lenguaje base que puedan ser utilizadas para estas funciones (un ejemplo de este tipo de LOA es COOL, el cual se describirá más adelante).

Los LOA de propósitos generales han sido diseñados para soportar cualquier tipo de aspectos. Este tipo de lenguajes no pueden imponer restricciones en el lenguaje base. Generalmente tienen el mismo nivel de abstracción que el lenguaje base, y soportan las mismas instrucciones o primitivas del lenguaje base, ya que, en principio, cualquier código debería poderse escribir en los aspectos desarrollados con estos lenguajes (un ejemplo de este tipo de LOA es AspectJ, el cual se describirá más adelante).

Los LOA de propósitos general tienen la clara ventaja de tener la capacidad de ser utilizados para desarrollar con ellos cualquier tipo de aspecto. Sin embargo, tienen también una desventaja ya que no garantizan la separación de funcionalidades. Al no poder restringir las instrucciones o primitivas en la programación de los componentes, no puede garantizarse que los aspectos no serán programados dentro de los componentes. Esto queda a libertad del programador.

Los LOA de dominio específico fuerzan a programar las tareas de aspectos dentro de estos, ya que en el lenguaje base se restringe el uso de las instrucciones que tienen relación con la funcionalidad de los aspectos.

El problema de los lenguajes base

Para el diseño de los LOA hay dos alternativas relativas al lenguaje base. Una sería el diseñar un nuevo lenguaje base junto con el lenguaje de aspectos y la otra sería tomar un lenguaje ya existente como base, lo cual es posible, ya que la base ha de ser un lenguaje de propósito general. Esta última opción tiene la ventaja de que se tiene que trabajar menos en el diseño e implementación de lenguajes para los entornos orientados a aspectos, y se pueden utilizar lenguajes ya trillados, y segundo, que el programador solamente tendrá que aprender el lenguaje de aspectos, pero no el lenguaje para la funcionalidad básica, que todavía constituye la mayor parte de los programas orientados a aspectos.

Hasta ahora, ambos, los lenguajes de dominio específicos y los de propósito general se han diseñado para utilizarse con lenguajes base existentes. Sin embargo, esta decisión también conlleva algunos problemas.

Con respecto a los lenguajes de dominio específico, puede tener bastante importancia el hecho de escoger un lenguaje base. Se tiene que tener en cuenta que los puntos de enlace solamente pueden ser los que se identifiquen en el lenguaje base. Así que no se es completamente libre para diseñar los puntos de enlace.

Segundo, si se necesitan separar las funcionalidades, se debe recordar que el lenguaje base debe restringirse después de que se hayan separado los aspectos. Esta es la parte más difícil, ya que se tiene que quitar elementos de un sistema complejo, el lenguaje base. Aunque el diseño de un lenguaje de programación es una tarea difícil y compleja, aún lo es más el hacerle cambios a un lenguaje, que no fue diseñado para tal propósito.

Los lenguajes de aspectos de propósito general son menos difíciles de implementar por encima de un lenguaje de programación existente, ya que no necesitan restringir el lenguaje base. Aparte de esto, la situación es la misma que con los lenguajes de dominio específicos, es decir, en el diseño de los puntos de enlace, se limita a los que pueden definirse en el lenguaje base.

JPAL

Esta herramienta enfatiza en los puntos de enlace, ya que son especificados independientemente del lenguaje base. Debido al término en inglés Junction Point, JPAL significa Junction Point Aspect Language, en español, Lenguaje de Aspectos basados en Puntos de Enlace.

El tejedor JPAL genera un esquema llamado Esquema del Tejedor. El cual desarrolló un mecanismo que automáticamente conecta el código base con los programas de aspectos en puntos de control(acciones).

El Esquema del Tejedor genera código que invoca, cuando es alcanzado en ejecución, las acciones correspondientes para permitir la ejecución de los programas de aspectos. Con lo cual se genera una vinculación dinámica con los programas de aspectos, y hace posible modificar en tiempos de ejecución los programas de aspectos. Sin embargo, esta solución no es lo suficientemente poderosa como para agregar o reemplazar programas de aspectos en ejecución. Para tal efecto se agrega al Esquema del Tejedor una entidad llamada Administrador de Programas de Aspectos (APA), el cual puede registrar un nuevo aspecto de una aplicación y llamar a métodos de aspectos registrados. Es implementado como una librería dinámica que almacena los aspectos y permite dinámicamente agregar, quitar o modificar aspectos, y mandar mensajes a dichos aspectos.

El Esquema Tejedor y APA se comunican mediante protocolo de comunicación entre procesos. La arquitectura de este lenguaje es la siguiente:

D

D es un ambiente de lenguajes de aspectos para la programación distribuida. Se denomina ambiente de lenguajes debido a que integra dos lenguajes, COOL, para controlar la sincronización de hilos, y RIDL, para programar la interacción entre componentes remotos. Estos dos lenguajes se diseñaron de manera independiente de un lenguaje componente. Sin embargo establecen un número de condiciones sobre este.

El diseño de D es semi-independiente del lenguaje componente, debido a que impone requerimientos sobre el lenguaje que también satisfacen los lenguajes orientados a objetos. Gracias a esto, el lenguaje componente puede ser cualquiera mientras sea orientado a objetos. Por lo tanto, podría ser implementado con C++, Smalltalk, CLOS, Java o Eiffel.

COOL

Los programas en COOL son comprendidos por un conjunto de módulos coordinadores. Estos módulos se asocian a las clases por medio del nombre, sin embargo, un mismo coordinador podría coordinar más de una clase. Mínimamente se puede sincronizar un método, y para declarar un coordinador, se debe describir la estrategia de coordinación.

Los coordinadores no son clases, utilizan un lenguaje diferente, por lo tanto tampoco pueden ser instanciados. Su asociación a las instancias de las clases se realiza automáticamente, utilizando un protocolo bien definido para su relación.

Los coordinadores tienen conocimiento de las clases que coordinan para definir la mejor estrategia de coordinación posible. Sin embargo, las clases no tienen conocimiento de los aspectos, es decir que dentro de una clase no es posible nombrar a un coordinador.

La asociación entre los objetos y los coordinadores es uno-a-uno por defecto y recibe el nombre de coordinación “per object”. Sin embargo, un coordinador también puede asociarse con todos los objetos de una o más clases y recibe el nombre de coordinación “per class”.

Protocolo de coordinación entre un módulo coordinador y un objeto.

El siguiente sería un aspecto implementado en COOL para la verificación en una cola circular.

El funcionamiento de COOL se da a partir de la definición de “Agents”, y de la gestión de las comunicaciones e interacciones entre ellos. Para estas interacciones, los Agentes usan protocolos de coordinación llamados “conversation classes”, los cuales definen las comunicaciones. Estas conversation classes pueden ser fácilmente representadas en diagramas de estados, en las cuales cada transición entre estas está descrita por una serie de reglas llamadas “conversation rules”.

Los objetos de COOL son los siguientes:

Agents: Son entidades autónomas, las cuales se comunican por paso de mensajes.

Conversation Classes: Es una lista de protocolos que usan los agents para comunicarse entre ellos.

Conversation Rules: Son un conjunto de reglas que describen las conversation classes según el momento o las condiciones en las que se encuentre el agent.

Continuation Rules: Son un conjunto de reglas que usan los agents para seleccionar la siguiente conversación que van a tener dependiendo de la conversación que están teniendo en el presente.

RIDL

RIDL (Remote Interaction and Data transfers aspect Language) es un lenguaje de aspectos de dominio específico que maneja la transferencia de datos entre diferentes espacios de ejecución.

Un programa RIDL consiste de un conjunto de módulos de portales. Los módulos de portales o directamente portales se asocian con las clases por el nombre. Un portal es el encargado de manejar la interacción remota y la transferencia de datos de la clase asociada a él, y puede asociarse como máximo a una clase. La unidad mínima de interacción remota es el método.

La declaración de los portales identifica clases cuyas instancias pueden invocarse desde espacios remotos. Dichas instancias se llaman objetos remotos. La declaración de un portal identifica qué métodos de una clase serán exportados sobre la red. En el portal estos métodos se llaman operaciones remotas. Para cada una de estas operaciones se describe qué objetos remotos esperan y qué datos enviarán a los llamadores.

Los portales no son clases, al igual que los coordinadores en COOL, no pueden ser instanciados y sirven para un propósito muy específico. Tampoco son tipos en el sentido estricto de la palabra. Un portal se asocia automáticamente con una instancia de la clase en el momento que una referencia a esa instancia se exporta fuera del espacio donde la instancia fue creada. Durante el tiempo de vida de la instancia esta relación se mantiene mediante un protocolo bien definido.

Este último punto establece una dependencia explícita entre los portales y la relaciones estructurales completas de las clases. Esta dependencia expone la necesidad de controlar la transferencia de datos entre los distintos espacios de ejecución.

Spring Python

Python, como tal, no requiere ningún tipo de extensión de lenguaje para poder hacer POA, dado que, además de algunas librerías, Python es capaz por si mismo de hacerlo. Sin embargo, existen proyectos que intentan agregar a Python varias herramientas y características para facilitar la inclusión de este paradigma. Entre los más notables está Spring Python, el cual es un proyecto desarrollado por Spring, con la intención de ser una versión de Spring Framework (Java) para Python.

AspectC

AspectC es un lenguaje de aspectos de propósito general que extiende C, es un subconjunto de AspectJ sin ningún soporte para la programación orientada a objetos o módulos explícitos. El código de aspectos, conocido como aviso, interactúa con la funcionalidad básica en los límites de una llamada a una función, y puede ejecutarse antes, después, o durante dicha llamada. Los elementos centrales del lenguaje tienen como objetivo señalar llamadas de funciones particulares, acceder a los parámetros de dichas llamadas, y adherir avisos a ellas.

Los puntos de corte en AspectC toman las siguientes formas:

Todos los cortes se pueden describir utilizando expresiones lógicas, aumentando la expresividad del lenguaje: el operador “y”(&&), el operador “o” (||), y el operador de negación(!). Un ejemplo sería: call(f(arg)) || call(h(arg)), con lo cual se captura las l lamadas a la función f o las llamadas a la función g.

Como el lenguaje C es de naturaleza estática, el tejedor de AspectC es estático.

AspectC++

AspectC++ es un lenguaje de aspectos de propósito general que extiende el lenguaje C++ para soportar el manejo de aspectos. En este lenguaje los puntos de enlace son puntos en el código componente donde los aspectos pueden interferir. Los puntos de enlaces son capaces de referir a código, tipos, objetos, y flujos de control.

Las expresiones de corte son utilizadas para identificar un conjunto de puntos de enlaces. Se componen a partir de los designadores de corte y un conjunto de operadores algebraicos. La declaración de los avisos es utilizada para especificar código que debe ejecutarse en los puntos de enlace determinados por la expresión de corte.

La información del contexto del punto de enlace puede exponerse mediante cortes con argumentos y expresiones que contienen identificadores en vez de nombres de tipos, todas las veces que se necesite. Diferentes tipos de aviso pueden ser declarados, permitiendo que el aspecto introduzca comportamiento en diferentes momentos: el aviso después (after advice), el aviso antes (before advice) y el aviso durante (around advice). Los aspectos en AspectC++ implementan en forma modular los conceptos entrecruzados y son extensiones del concepto de clase en C++. Además de atributos y métodos, los aspectos pueden contener declaraciones de avisos. Los aspectos pueden derivarse de clases y aspectos, pero no es posible derivar una clase de un aspecto.

AspectJ

Extensión Java del proyecto Eclipse para soportar el manejo de aspectos agregando a la semántica de Java las cuatro entidades ya descritas:

Algunas ventajas de este lenguaje son:

Sin embargo, algunas posibles desventajas son:

El siguiente es un ejemplo implementado en AspectJ para registro de transacciones bancarias.

Otra característica es que tiene distintos tipos de Advice, 'before', 'after', 'after returning', 'after throwing' , y'around' advice, permitiendo una intervención detallada en los puntos de corte.

Finalmente, se puede argumentar que es la extensión de lenguaje más usada en cuanto a POA, debido a que es una de las más desarrolladas y a que es particularmente fácil de entender y utilizar.

Proceso de compilación en AspectJ

AspectJ utiliza un compilador diferente al compilador de Java, el cual es el ajc (AspectJ Compiler) este compilador es bastante versátil ya que nos ofrece varias opciones al momento de crear el tejido.

Por un lado, tenemos el siguiente panorama: Tenemos el modelado de clases en java (archivos con extensión .java), Aspectos con notación @aspect (También con extensión .java) y Aspectos usando el lenguaje AspectJ (estos con extensión .aj). El compilador ajc nos permite compilar todos estos elementos en una sola pasada generando el archivo de bytecodes o tejido (extensión .class o .jar) el cual podrá ser interpretado haciendo uso de la Máquina Virtual de Java.

En el siguiente diagrama se muestra como se realiza el proceso de compilación de un proyecto segun el paradigma de aspectos para AspectJ

Por otro lado, en caso en el cual contemos con código ya compilado o con proyectos muy grandes cuyo proceso de compilación sea bastante tardio, el compilador ajc nos permite generar el tejido del proyecto usando archivos ya en bytecodes y archivos de código fuente. El ajc puede recibir archivos con extensiones jar, class, java, aj para generar el tejido listo para la interpretación por parte de la Máquina Virtual de Java.

El proceso anterior se puede visualizar de la siguiente manera:

AspectS

AspectS, un lenguaje de aspectos de propósito general, utiliza el modelo de lenguaje de AspectJ y ayuda a descubrir la relación que hay entre los aspectos y los ambientes dinámicos. Soporta programación en un metanivel, manejando el fenómeno de Código Mezclado a través de módulos de aspectos relacionados. Está implementado en Squeak sin cambiar la sintaxis, ni la máquina virtual.

En este lenguaje los aspectos se implementan a través de clases y sus instancias actúan como un objeto, respetando el principio de uniformidad. Un aspecto puede contener un conjunto de receptores, enviadores o clases enviadoras. Estos objetos se agregan o se remueven por el cliente y serán usados por el proceso de tejer en ejecución para determinar si el comportamiento debe activarse o no.

Los tipos de avisos definibles en AspectS son:

Un calificador de avisos (AsAdviceQualifier) es usado para controlar la selección del aviso apropiado. Es similar al concepto de designadores de cortes de AspectJ.

Utiliza un tejedor dinámico que transforma el sistema base de acuerdo a lo especificado en los aspectos. El código tejido se basa en el MethodWrapper y la meta-programación. MethodWrapper es un mecanismo que permite introducir código que es ejecutado antes, después o durante la ejecución de un método.

El proceso de tejer sucede cada vez que una instancia de aspectos es instalada. Para revertir los efectos de un aspecto al sistema, el aspecto debe ser desinstalado. A este proceso se lo conoce como “destejer”, del inglés unweaving. El tejido de AspectS es completamente dinámico ya que ocurre en ejecución.

MALAJ

MALAJ (Multi Aspect Language for Java) es un lenguaje orientado a aspectos de dominio específico. Define constructores lingüísticos separados para cada aspecto de dominio específico, donde el código de los aspectos tiene una visibilidad limitada del código funcional, reduciendo los posibles conflictos con las características lingüísticas tradicionales y también, con el principio de encapsulación.

Se concentra principalmente en dos aspectos: sincronización y relocación. Puede verse como un sucesor de los lenguajes COOL y RIDL por su filosofía, enfatizando la necesidad de restringir la visibilidad de los aspectos, y reglas claras de composición con los constructores tradicionales. Para cada aspecto, provee un constructor lingüístico distinto, limitando así la visibilidad del aspecto sobre el módulo funcional asociado a él. Esto último se logra al estudiar cuidadosamente la relación entre el código funcional y un aspecto dado.

El lenguaje base de Malaj es una versión restringida de Java, donde se han removido los servicios que proveen los aspectos mencionados. Los servicios removidos son: la palabra clave synchronized, y los métodos wait, notify, and notifyAll.

Para el aspecto de sincronización Malaj provee el constructor guardian. Cada guardián es una unidad distinta con su propio nombre, y se asocia con una clase en particular (esto es, “vigila” esa clase) y expresa la sincronización de un conjunto relacionado de métodos de esa clase, es decir, que el guardián de una clase V representa básicamente el conjunto de métodos sincronizados de V .

Los guardianes no pueden acceder a los elementos privados de la clase que vigilan, y el acceso a los atributos públicos y protegidos se limita a un acceso de sólo lectura. El comportamiento adicional en un guardián para un método m de la clase asociada se especifica introduciendo código que se ejecutará antes o después de m, a través de las cláusulas before y after. Una última característica de los guardianes es que pueden heredarse. Para reducir el problema de anomalía de herencia las cláusulas before y after en una clase pueden referirse a las cláusulas before y after de su clase padre a través de la sentencia super.

El aspecto de relocación involucra el movimiento de objetos entre sitios en un ambiente de redes. Este tipo de relación es claramente dinámico. Para este aspecto Malaj provee el constructor relocator, que llamaremos relocador. Un relocador será una unidad diferente con su propio nombre, y se asocia con una clase en particular. Las acciones de relocación pueden ejecutarse antes o después de la ejecución de un método. Para modelar este comportamiento, el relocador brinda cláusulas before y after, que permiten la especificación deseada. También la visibilidad del relocator es limitada. Como el constructor guardián, un relocador puede heredarse, y las cláusulas before y after en una clase pueden referirse a las cláusulas before y after de su clase padre a través de la sentencia super, y así reducir el impacto de la anomalía de herencia.

Como conclusión Malaj provee una solución intermedia entre flexibilidad y poder por un lado, y entendimiento y facilidad de cambio por el otro. No permite describir cualquier aspecto, pero sí captura el comportamiento de dos conceptos relacionados con el código funcional.

HyperJ

La aproximación por Ossher y Tarr sobre la separación multidimensional de conceptos (MDSOC) es llamada hyperspaces, y como soporte se construyó la herramienta HyperJ en Java (ver Separación multidimensional de conceptos) .

En HyperJ un hiperespacio (hyperspace) es un espacio de concepto especialmente estructurado para soportar la múltiple separación de conceptos. Su principal característica es que sus unidades se organizan en una matriz multidimensional donde cada eje representa una dimensión de concepto y cada punto en el eje es un concepto en esa dimensión.

Los hiperslices son bloques constructores pueden integrarse para formar un bloque constructor más grande y eventualmente un sistema completo.

Un hipermódulo consiste de un conjunto de hiperslices y conjunto de reglas de integración, las cuales especifican cómo los hiperslices se relacionan entre ellos y cómo deben integrarse.

Una vez introducida la terminología se puede continuar con el análisis de HyperJ. Esta herramienta permite componer un conjunto de modelos separados donde cada uno encapsula un concepto definiendo e implementando una jerarquía de 20 clases apropiada para ese concepto. Generalmente los modelos se superponen y pueden o no referenciarse entre ellos. Cada modelo debe entenderse por sí solo. En la siguiente tabla se encuentran resumidas las principales características de las herramientas orientadas a aspectos descriptas en los párrafos anteriores:

Aspect(PERL)

Perl es un acrónimo de Practical Extracting and Reporting Languaje. Es práctico para extraer información de archivos de texto y generar informes a partir del contenido de los ficheros. Aspect es un módulo de Perl que le permite al lenguaje soportar la Programación Orientada a Aspectos. Su uso básico sería el siguiente:

Python

Python no necesita de ningún plug-in o librería para hacer POA. ya que esto lo puede lograr mediante los decorators. El uso mediante decoradores sería de la siguiente manera:

Sin embargo existen algunas librerias que nos brindan ayuda para este tipo de desarrollo, como por ejemplo:

AspectLib

Aspectlib es una biblioteca que facilita la implementación de AOP en Python, que nos proporciona una manera organizada y consistente de definir y aplicar aspectos ademas de la posibilidad de reutilizar y aplicar estos en distintos puntos de corte de manera efectiva. Tambien soporta múltiples tipos de advice (before, after, around), lo que puede ser más complicado de implementar con decoradores nativos.

Ruby

AspectR

Lanzada en 2001, AspectR es una gema AOP para el lenguaje Ruby, por Avi Bryant y Robert Feldt. Su última actualización fue en 2006. Actualmente no es mantenida.

Aquarium

Es un framework que implementa AOP para Ruby. Aquarium proporciona un Lenguaje de Dominio Específico (DSL) con el que se puede expresar el comportamiento "aspectual" del sistema de forma modular.

Module

Es un "prepend" que está incluido en en propio lenguaje Ruby, que permite la programación orientada a aspectos. Se define como una colección de métodos y constantes. Los métodos de un módulo pueden ser métodos de instancia o métodos de módulo.

.Net Framework

PostSharp

Es una aplicación comercial de AOP para .NET con una edición gratuita pero limitada. A diferencia de muchos otros idiomas, C# carece de un mecanismo moderno de descomposición de problemas para hacer frente a características como el registro o el almacenamiento en caché, patrones de diseño como INotifyPropertyChanged, o modelos de enhebrado como inmutable o hilo afín.Por lo tanto, los desarrolladores deben escribir toneladas de código repetitivo de bajo nivel que requiere poco ingenio pero que es altamente propenso a errores: el notorio "boilerplate".

Postsharp, con ayuda de la modularización del paradigma AOP, promete un código más corto y limpio, de fácil mantenimiento y aplicaciones confiables.

Postsharp soporta varios tipos de advice (OnEntry, OnExit, OnException, Around), permitiendo intervenciones específicas en el flujo de ejecución. Tambien proporciona aspectos predefinidos para tareas comunes como caching, threading, y validación.

Lua

AspectLua

AspectLua es una extensión de Lua para la programación orientada a aspectos. Sigue algunos conceptos de AspectJ, y permite la creación de Aspectos para modularizar "preocupaciones transversales" en objetos escritos en Lua puro.

PHP

PHP cuenta con varias implementaciones a través de los años, entre estas encontramos:

MatLab

AspectMatlab

AspectMatlab introduce características clave orientadas a aspectos de una manera que es accesible para los científicos y donde las características orientadas a aspectos se concentran en los accesos a arreglos y bucles, los elementos centrales en los programas científicos.

Introducir aspectos en un lenguaje dinámico como Matlab también proporciona algunos nuevos desafíos. En particular, es difícil determinar estáticamente con precisión dónde coinciden los patrones, lo que da lugar a muchas comprobaciones dinámicas en el código tejido. El compilador AspectMatlab (amc) incluye análisis de flujo que se utilizan para eliminar muchas de esas comprobaciones dinámicas (Tomado de AspectMatLab).

Spring AOP

Este framework es implementado en java puro con las anotaciones de java @Aspect o basado en esquema con un XML. Este permite la implementación del paradigam POA mediante AspectJ. La siguiente sería su implementación básica:

AspectJ vs Spring AOP

Junto con AspectJ, son los dos principales frameworks de AOP para JAVA, sin embargo tienen objetivos distintos.

Objetivos

Spring AOP busca proveer una implementación simple del Paradigma Orientado a Aspectos, para solucionar los problemas más comunes que los programadores enfrentan. Por otra parte, AspectJ sí busca proveer una implementación completa del paradigma interoperable con el código de java existente.

Weaving

AspectJ hace uso de tres tipos distintos de weaving:

  1. Compile-time weaving: El compilador de AspectJ toma como entrada el código fuente del aspecto y de la aplicación y las compone para crear bytecode de JAVA listo para ser procesados por la JVM.
  2. Post-compile weaving: Es usado para enlazar las los aspectos con bytecode de java y JAR existentes.
  3. Load-time weaving: Es similar al weaving anterior, solo que se pospone hasta que un cargador de clases carga los archivos a la JVM.
Sprint AOP hace uso de un weaving en tiempo de ejecución, similar al load-time weaving de AspectJ.

Simplicidad

Spring AOP es mucho más simple porque no introduce ningún compilador extra o weaver en el proceso de compilación. Sin embargo, esto le quita mucha potencia a lo que puede ser realizado con el Framework. AspectJ por otra parte introduce el AspectJ compiler (ajc) y con él compila todas las clases que tenemos, tanto las .java como las .aj, lo que lo hace más complejo porque introduce nuevas herramientas pero también lo hace más potente.

Performance

El compile-time weaving del AspectJ es mucho más rápido que el runtime weaver del Spring AOP. Sprint AOP es un framework basado en proxy, por lo tanto en tiempo de ejecución se están creando proxies. También, se ejecutan otros métodos de fondo, por lo tanto se crea un overload significativo. Por otra parte, AspectJ teje los aspectos en el código principal antes de que la aplicación entre en ejecución, por lo tanto no existe un overhead adicional. Por estas razones, AspectJ es alrededor de 8 y 35 veces más rápido que SpringAOP.

Escoger el framework adecuado

Si analizamos todos los argumentos de esta sección, empezaremos a entender que no se trata en absoluto de que un framework sea mejor que otro. En pocas palabras, la elección depende en gran medida de nuestros requisitos:

  1. Framework: Si la aplicación usa el framework de Spring con otros propósitos, el uso del AOP será bastante sencillo de aprender y usar. Sin embargo, si esto no es así, habrá que integrar el proyecto y adaptarlo para que haga uso del mismo, lo cual podría complicar un poco el procesos.
  2. Flexibilidad: Spring AOP no soporta todos los Joinpoints, pero sí los suficientes para resolver los problemas más comunes que se presentan durante el desarrollo en JAVA. No obstante, si se necesita otro tipo de Joinpoint, será necesario usar AspectJ.
  3. Rendimiento: Si se usan aspectos limitados, entonces habrán diferencias de desempeño. Si es necesario usar una gran cantidad de aspectos, AspectJ es la mejor opción debido a su mejor rendimiento.
  4. Mejor de ambos: Ambos de estos aspectos son completamente compatibles con los otros. Podemos aprovechar el Spring AOP framework cuando sea posible y aún usar AspectJ para obtener soporte de aquellos JoinPoints que sean necesarios.

Referencias: