Aspecto La programación orientada a objetos (AOP) complementa la programación orientada a objetos (POO) al proporcionar una forma diferente de pensar sobre la estructura del programa. La unidad clave de modularidad en OOP es la clase, mientras que en AOP la unidad de modularidad es el aspecto. Los aspectos permiten una organización modular de funcionalidad (como la gestión de transacciones) que abarca múltiples tipos y objetos. (En la literatura de AOP, esta funcionalidad a menudo se denomina "transversal").

Uno de los componentes clave de Spring es el marco AOP. Aunque el contenedor IoC de Spring es independiente de AOP (lo que significa que no tiene que usar AOP si no lo desea), AOP complementa Spring IoC, lo que resulta en una solución de middleware muy adecuada.

Spring AOP usando cortes de AspectJ

Spring ofrece formas sencillas y con todas las funciones de escribir aspectos personalizados utilizando el enfoque basado en esquemas o el estilo de anotación @AspectJ. Ambos estilos admiten Advice completamente escrito y la capacidad de usar el lenguaje de corte AspectJ, pero aún usan Spring AOP para el enlace.

Este capítulo cubre el soporte para AOP basado en esquemas y @AspectJ.

AOP se utiliza en Spring Framework para:

  • Proporcionar servicios empresariales declarativos. El servicio más importante es la gestión de transacciones declarativas.

  • Permite a los usuarios implementar aspectos especiales, complementando el uso de POO con AOP.

Si solo está interesado en servicios declarativos genéricos u otros servicios de middleware declarativo sin preparación, como la agrupación, entonces no tendrá que trabajar directamente con Spring AOP. , por lo que puede omitir con seguridad la mayor parte de este capítulo.

Conceptos de AOP

Comencemos definiendo algunos conceptos y terminología básicos de AOP. Estos términos no son específicos de Spring. Desafortunadamente, la terminología de AOP no es particularmente intuitiva. Sin embargo, se vuelve aún más confuso si Spring usa su propia terminología.

  • Aspecto: una funcionalidad (preocupación) organizada modularmente que abarca múltiples clases. La gestión de transacciones es un buen ejemplo de funcionalidad de un extremo a otro en aplicaciones Java empresariales. En Spring AOP, los aspectos se implementan utilizando clases regulares (enfoque basado en esquemas) o clases regulares anotadas con la anotación @Aspect (@estilo AspectJ).

  • Punto conjunto: un punto durante la ejecución del programa, como ejecutar un método o manejar una excepción. En Spring AOP, un punto de conexión siempre representa la ejecución de un método.

  • Consejo: La acción realizada por un aspecto en un punto de conexión específico. Los diferentes tipos de Consejos incluyen Consejos "alrededor", "antes" y "después". (Los tipos de consejos se analizarán más adelante). Muchos marcos de AOP, incluido Spring, modelan Advice como un interceptor y admiten una cadena de interceptores en lugar de un punto de unión.

  • Pointcut: un predicado que coincide con puntos de unión. El consejo está asociado con una expresión de segmento y se ejecuta en cualquier punto de conexión que coincida con el segmento (por ejemplo, ejecutando un método con un nombre específico). El concepto de puntos de unión asignados a expresiones de corte es fundamental para AOP, y Spring usa el lenguaje de expresión de corte AspectJ de forma predeterminada.

  • Introducción: declaración de métodos o campos adicionales en nombre del tipo . Spring AOP le permite implementar nuevas interfaces (y la implementación correspondiente) en cualquier objeto habilitado para Advice. Por ejemplo, puede utilizar la inyección para forzar al bean a implementar la interfaz IsModified para facilitar el almacenamiento en caché. (En la comunidad de AspectJ, una introducción se conoce como declaración entre tipos).

  • Objeto de destino: un objeto que recibe asesoramiento sobre uno o más aspectos. También se denomina objeto proporcionado por asesoramiento. Debido a que Spring AOP se implementa mediante proxies dinámicos, este objeto siempre es un objeto proxy.

  • Proxy AOP: un objeto creado por el marco AOP para implementar contratos de aspecto (proporciona asesoramiento con método ejecución, etc.). En Spring Framework, un proxy AOP es un proxy JDK dinámico o un proxy CGLIB.

  • Tejido: vincula aspectos con otros tipos de aplicaciones u objetos para crear un objeto equipado con consejos. Puede producirse en tiempo de compilación (por ejemplo, utilizando el compilador AspectJ), en tiempo de carga o en tiempo de ejecución del programa. Spring AOP, al igual que otros marcos de Java AOP puros, realiza el enlace en tiempo de ejecución.

Spring AOP incluye los siguientes tipos de consejos:

  • Antes de la sugerencia: una sugerencia que se ejecuta antes del punto de unión, pero no tiene forma de evitar que el hilo de ejecución vaya al punto de unión (a menos que genere una excepción).

  • Pista "después de regresar": Consejo que se ejecutará después de que el punto de conexión haya salido normalmente (por ejemplo, si el método regresa sin lanzar una excepción).

  • Consejo de lanzamiento : El consejo que se ejecutará si el método sale lanzando una excepción.

  • Después del consejo (finalmente)": El consejo debe ejecutarse independientemente de la forma en que esté el punto de unión salió (ya sea un retorno normal o excepcional).

  • Consejo aproximado: una sugerencia que rodea el punto de unión, como llamar a un método. Este es el tipo de consejo más eficaz. El consejo "en lugar" puede seguir una lógica operativa especial antes y después de la llamada al método. También es responsable de elegir si saltar a un punto de unión o atajar el método recomendado devolviendo su propio valor de retorno o lanzando una excepción.

El consejo "en lugar" es el tipo de consejo más general. Dado que Spring AOP, al igual que AspectJ, proporciona una gama completa de tipos de consejos, recomendamos utilizar el tipo de consejo menos potente que pueda implementar la lógica operativa requerida. Por ejemplo, si solo necesita actualizar el caché con el valor de retorno de un método, entonces es mejor implementar el consejo posterior al retorno que el consejo en lugar, aunque el consejo en lugar puede hacer lo mismo. El uso del tipo de asesoramiento más específico proporciona un modelo de programación más simple con menos posibilidades de errores. Por ejemplo, no necesita llamar al método proceed() en el JoinPoint usado para el consejo "en lugar" y, por lo tanto, no puede evitar llamarlo.

Todos los parámetros de asesoramiento se escriben estáticamente, por lo que se trabaja con parámetros de asesoramiento del tipo apropiado (por ejemplo, el tipo de valor de retorno al ejecutar un método), en lugar de con matrices Object. .

El concepto de puntos de unión asignados a sectores es la clave para comprender AOP, lo que lo distingue de tecnologías más antiguas que solo ofrecen intercepción. Los sectores permiten abordar los consejos independientemente de la jerarquía orientada a objetos. Por ejemplo, puede aplicar el consejo "en lugar", que proporciona gestión de transacciones declarativas, a un conjunto de métodos que abarcan múltiples objetos (por ejemplo, todas las operaciones comerciales a nivel de servicio).

Características de Spring AOP y Goals

Spring AOP se implementa en Java puro. No es necesario un proceso de compilación especial. Spring AOP no requiere administración de jerarquía del cargador de clases y, por lo tanto, es adecuado para su uso en un contenedor de servlets o servidor de aplicaciones.

Spring AOP actualmente solo admite puntos de unión de ejecución de métodos (que brindan consejos de ejecución de métodos a Spring beans). La interceptación de campos no está implementada, aunque se podría agregar soporte para la interceptación de campos sin romper las API principales de Spring AOP. Si necesita brindar asesoramiento sobre el acceso al campo y actualizar los puntos de unión, considere un lenguaje como AspectJ.

El enfoque de Spring AOP hacia AOP difiere de la mayoría de los otros marcos de AOP. El objetivo no es proporcionar la implementación más completa de AOP (aunque Spring AOP es bastante capaz de hacerlo). Más bien, el objetivo es proporcionar una estrecha integración entre una implementación de AOP y Spring IoC, lo que ayudará a resolver problemas comunes en las aplicaciones empresariales.

Por ejemplo, la funcionalidad AOP en Spring Framework se usa normalmente junto con COI Contenedor de resorte. Los aspectos se configuran utilizando la sintaxis de definición de bean normal (aunque esto permite capacidades de "proxy automático" de alto rendimiento). Esta es una diferencia fundamental con respecto a otras implementaciones de AOP. No podrá hacer algunas cosas de manera fácil y eficiente con Spring AOP, como brindar asesoramiento a objetos de escala extremadamente pequeña (generalmente objetos de dominio). AspectJ es la mejor opción en tales casos. Sin embargo, nuestra experiencia ha sido que Spring AOP proporciona una solución excelente para la mayoría de los problemas de las aplicaciones Java empresariales que se prestan a AOP.

Spring AOP de ninguna manera ha intentado competir con AspectJ en el suministro de una solución integral para POA. Creemos que tanto los marcos basados en proxy como Spring AOP como los marcos completos como AspectJ son valiosos y se complementan entre sí en lugar de competir. Spring integra perfectamente Spring AOP e IoC con AspectJ, lo que le permite utilizar AOP dentro de una arquitectura de aplicaciones consistente basada en Spring. Esta integración no afecta a la API Spring AOP ni a la API AOP Alliance. Spring AOP sigue siendo compatible con versiones anteriores.

Uno de los principios básicos de Spring Framework es la no invasividad. La idea es no obligarlo a implementar clases e interfaces específicas del marco en su modelo de negocio o dominio. Sin embargo, en algunos puntos, Spring Framework le brinda la posibilidad de inyectar dependencias específicas de Spring Framework en su código base. El objetivo de proporcionar tales capacidades es que, en ciertos escenarios, simplemente puede ser más fácil leer o codificar ciertas funciones de esta manera. Sin embargo, Spring Framework (casi) siempre ofrece una opción: usted tiene la oportunidad de tomar una decisión informada sobre qué opción es mejor para su caso de uso o caso de uso específico.

Una de esas opciones que es relevante para En este capítulo, esta es la elección de un marco AOP (y un estilo AOP). Tiene las siguientes opciones: AspectJ, Spring AOP o ambos. También tiene la opción de elegir entre un enfoque de estilo de anotación @AspectJ o un enfoque de estilo de configuración Spring XML. El hecho de que hayamos elegido presentar el enfoque de estilo @AspectJ primero en este capítulo no debe tomarse como una indicación de que el equipo de Spring prefiere el enfoque de estilo de anotación @AspectJ sobre el enfoque de estilo de configuración Spring XML.

AOP Proxy

Spring AOP utiliza servidores proxy dinámicos JDK estándar para servidores proxy AOP de forma predeterminada. Esto le permite representar cualquier interfaz (o conjunto de interfaces).

Spring AOP también puede usar un proxy CGLIB. Son necesarios para representar clases, no interfaces. De forma predeterminada, se utiliza CGLIB si el objeto comercial no implementa la interfaz. Debido a que se recomienda programar interfaces en lugar de clases, las clases de negocios generalmente implementan una o más interfaces de negocios. Puede forzar el uso de CGLIB en aquellos casos (con suerte raros) en los que necesita brindar asesoramiento sobre un método no declarado en una interfaz. o cuando necesita pasar un objeto proxy de método como un tipo concreto.

Es importante comprender que Spring AOP se basa en un proxy.