Uso de proxies en Spring AOP

Estoy leyendo un libro, que habla sobre cómo habilitar el apoyo de AspectJ en Spring AOP.

A continuación se incluye un párrafo tomado del libro:

Para habilitar el soporte de anotación AspectJ en el contenedor Spring IoC, solo tiene que definir un elemento XML vacío aop: aspectj-autoproxy en su archivo de configuración de beans. Luego, Spring creará automáticamente proxies para cualquiera de sus beans que coincidan con sus aspectos AspectJ.

Para los casos en que las interfaces no están disponibles o no se utilizan en el diseño de una aplicación, es posible crear proxies confiando en CGLIB. Para habilitar CGLIB, debe establecer el atributo proxy-targetclass = true en aop: aspectj-autoproxy.

No puedo obtener el segundo párrafo. Lo que significa ‘las interfaces no están disponibles ‘. ¿Alguien puede ilustrar esto con un ejemplo?

Spring AOP utiliza proxies dynamics JDK o CGLIB para crear los proxies para sus objetos de destino.

Según la documentación de Spring, en caso de que su objective implemente al menos una interfaz, se usará un proxy dynamic JDK. Sin embargo, si su objeto de destino no implementa ninguna interfaz, se creará un proxy CGLIB.

Así es como puede forzar la creación de los proxies CGLIB (set proxy-target-class = ” true “):

   

Al usar AspectJ y su soporte de autopoxy, también puede forzar los proxies CGLIB. Aquí es donde se usa y también aquí la “proxy-target-class” debe establecerse en verdadero :

  

Consulte la sección Mecanismos de proxy de Progtwigción Orientada a Aspectos con la documentación de Spring para más detalles.

Spring prefiere usar interfaces para AOP porque puede usar proxies JDK.

Digamos, por ejemplo, tengo una interfaz MyService

 public interface MyService { void doSomething(); } 

Y una implementación MyServiceImpl

 @Service public class MyServiceImpl implements MyService { public void doSomething() { // does something! } } 

Si Spring descubre que ha configurado aspectos para MyService , creará un JDK Proxy que implementará MyService y luego realizará un proxy de todas las llamadas a su bean MyServiceImpl , agregando funcionalidad aspect cuando corresponda.

Los proxies JDK funcionan implementando la misma interfaz que su objeto de destino y delegando llamadas a ella; no funcionan si no hay una interfaz para implementar. En caso de que no tenga una interfaz como la anterior, Spring necesita usar una biblioteca de códigos de bytes como CGLIB para crear dinámicamente clases en tiempo de ejecución que incorporen la funcionalidad de aspecto.

Encontré un blog aquí que explica claramente cómo funciona AOP, Caching & Transaction con clases de proxy en tiempo de ejecución.

Cuando no está codificando para la interfaz (citando de la sección del blog ‘ ¿Qué pasa si la clase de bean no implementa ninguna interfaz? ‘): –

De forma predeterminada, si su bean no implementa una interfaz, Spring utiliza la herencia técnica: en el momento del inicio, se crea una nueva clase. Hereda de su clase de bean y agrega comportamiento en los métodos secundarios. Para generar dichos proxies, Spring usa una biblioteca de terceros llamada cglib.

Spring AOP hace un uso extensivo de proxies como un mecanismo para implementar preocupaciones transversales (también conocidos como aspectos) de una manera no intrusiva, la idea es básicamente usar los proxies como envoltorios que enriquecen el comportamiento original, es decir, agregan capacidades transaccionales.

Para lograr esto, hay dos opciones, dependiendo de si el objeto original implementa una interfaz o no.

En el primer caso (el objeto original implementa al menos una interfaz) las capacidades de proxy dynamic de la API de reflexión se utilizan para crear un objeto proxy que IMPLEMENTE las mismas interfaces que el objeto original y, por lo tanto, el proxy puede usarse en su lugar.

En el segundo caso (el objeto original NO implementa ninguna interfaz), se debe usar un truco más elaborado, y es entonces cuando aparece CGLIB. De acuerdo con la página del proyecto “CGLIB se usa para extender clases Java e implementa interfaces en tiempo de ejecución”. Entonces, en este caso, el truco consiste en crear un proxy que EXTIENDE el objeto original y, por lo tanto, puede usarse en su lugar.