Spring AOP: registro y métodos anidados
He escrito una aplicación Spring2.5 simple para demo / prueba AOP; específicamente, quiero registrar la entrada y salida de cada método de cada clase en un paquete específico. Esto es lo que tengo..
(nota: estoy usando controladores de anotación; estoy omitiendo detalles que no están directamente relacionados con aop porque mi configuración básica funciona bien; solo incluyo detalles relacionados con aop; avíseme si necesita ver más)
applicationContext.xml:
(...)
<bean id="loggerInterceptor" class="aspect.LoggerInterceptor" />
(...)
dispatcher-servlet.xml:
(...)
<aop:aspectj-autoproxy proxy-target-class="true" />
(...)
HomeController.java:
public class HomeController() {
public HomeController() { }
public ModelAndView get() {
System.out.println("In HomeController#get()...");
this.somePrivateMethod();
this.somePublicMethod();
return new ModelAndView( "home" );
}
private void somePrivateMethod() {
System.out.println("In HomeController#somePrivateMethod()...");
}
public void somePublicMethod() {
System.out.println("In HomeController#somePublicMethod()...");
}
}
LoggerInterceptor.java:
public class LoggerInterceptor {
@Pointcut("execution(* controller.*.*(..))")
private void anyOperationInControllerPackage() {
/* nothing to do here;
* this just defines that we want to catch all methods
* in the controller-package
*/
}
@Around("anyOperationInControllerPackage()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Entering " + joinPoint.getSignature().getDeclaringTypeName() + "#" + joinPoint.getSignature().getName() + "() using arguments: " + Arrays.toString( joinPoint.getArgs() ) );
try {
Object result = joinPoint.proceed();
System.out.println("Leaving " + joinPoint.getSignature().getDeclaringTypeName() + "#" + joinPoint.getSignature().getName() + "()." );
return result;
} catch (Throwable ex) {
ex.printStackTrace();
throw ex;
}
}
}
Esto es lo que obtengo cuando se invoca HomeController # get ():
Entering controller.HomeController#get() using arguments: []
In HomeController#get()...
In HomeController#somePrivateMethod()...
In HomeController#somePublicMethod()...
Leaving controller.HomeController#get().
Como puede ver, el único método que está siendo interceptado es HomeController # get (). Cuando #get () llama a #somePrivateMethod () o #somePublicMethod (), el interceptor no los detecta. Esperaría, al menos, que #somePublicMethod () también quedara atrapado (y como estoy usando cglib, también esperaría que #somePrivateMethod () quede atrapado).
Así que supongo que mi pregunta es qué necesito cambiar / agregar para permitir (al menos) que todos los métodos públicos en el paquete controlador sean atrapados incluso cuando otro método en ese paquete los llamó y fue atrapado primero ???
Espero que tenga sentido. :R
EDIT (25APR2011 @ 1:13 PM)applicationContext.xml:
(...)
<context:load-time-weaver /> <!-- added -->
<bean id="loggerInterceptor"... />
(...)
aop.xml:
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- only weave classes in this package -->
<include within="controller.*" />
</weaver>
<aspects>
<!-- use only this aspect for weaving -->
<aspect name="aspect.LoggerInterceptor" />
</aspects>
</aspectj>
En las "Propiedades del proyecto" de Netbean en la pestaña "Ejecutar", agregué esta línea a las "Opciones de VM" :
-javaagent:C:\Users\bgresham\Documents\libraries\spring-framework-2.5\dist\weaving\spring-agent.jar
Como antes, no recibo ningún error, simplemente no obtengo el registro "anidado" que estoy buscando.
???