Leí que Spring AOP no puede interceptar métodos privados y protegidos, pero los intercepta de una manera extraña, ¿por qué?
Tengo estas funciones que quiero interceptar:
public String getName(String string) { System.out.println("Name : " + name + string); return name; } protected String getNamesprotected(String string) { System.out.println("Name : " + name + string); return name; } Este es mi código @Aspect :
@Aspect public class Logging { @Before("execution(* com.tutorialspoint.Student.*Name*(..))") public void beforeAdvice(JoinPoint joinPoint){ System.out.println("Going to setup student profile."+joinPoint.getSignature().toString()); } }Cuando se ejecuta este código, tanto getName como getNamesprotected son interceptados, pero cuando ejecuto este código:
@Aspect public class Logging { @Before("execution(* com.tutorialspoint.Student.getNamesprotected(..))") public void beforeAdvice1(JoinPoint joinPoint){ System.out.println("Going to setup student profile."+joinPoint.getSignature().toString()); } } Entonces nada es interceptado. También intenté reemplazar getNamesprotected con *getNamesprotected* pero aún así no intercepta. Solo intercepta cuando *Name* está allí.
¿Alguien puede explicarme por qué sucede esto?
Debido a que el OP (Prateek Gupta) parecía incapaz (más bien no dispuesto) de crear un pequeño SSCCE que reprodujera el problema y estaba aburrido durante una pausa para el té, rápidamente creé uno solo con Spring Boot y me sorprendió mucho que, de hecho, Spring AOP , en contradicción con la documentación, al menos bajo ciertas circunstancias coincide con métodos protegidos cuando se trata de proxies CGLIB.
Por lo tanto, registré una cuenta para el rastreador de problemas Jira de Spring e informé esta regresión como SPR-15354 . Es posible que desee suscribirse para recibir actualizaciones sobre ese ticket si está interesado en las respuestas del equipo de desarrollo de Spring.
Actualización: la persona que respondió a mi ticket me dijo que se trata de un problema de documentación. Como nos dice SPR-1611 de 2006, esto ya se cambió a propósito para Spring 1.2.7, pero nunca llegó a la documentación. En pocas palabras: los métodos protegidos se pueden capturar a través de Spring AOP, no es un accidente, pero ha estado sin documentar durante 12 años.
Actualización 2: El texto de la documentación actualizada estará en la próxima versión de primavera. Si desea leer el texto fijo hoy, se cita en SPR-1611 .
¿Alguien puede explicarme por qué sucede esto?
Debido a la naturaleza basada en proxy del marco AOP de Spring, los métodos protegidos, por definición, no son interceptados, ni para los proxies JDK (donde esto no es aplicable) ni para los proxies CGLIB (donde esto es técnicamente posible pero no recomendable para fines AOP).
Como consecuencia, cualquier punto de corte dado se comparará solo con métodos públicos.
Si sus necesidades de intercepción incluyen métodos protegidos/privados o incluso constructores, considere el uso de tejido AspectJ nativo impulsado por Spring en lugar del marco AOP basado en proxy de Spring.
Cuando se ejecuta este código, tanto getName como getNamesprotected son interceptados.
@Before("execution(* com.tutorialspoint.Student.*Name*(..))")Aquí, el comodín anterior coincide con los métodos con cualquier modificador (público, protegido y privado) y cualquier tipo de devolución. Los dos puntos en la lista de argumentos coinciden con cualquier número de argumentos.
Prueba esto, debería ejecutar tu método protegido.
@Pointcut("execution(protected * *.*(..))")También puedes probar esto si te funciona (no estoy 100% seguro)
@Before("execution(* com.tutorialspoint.Student+.getNamesprotected(..))")