I have written a simple Spring2.5 app to demo/test AOP; specifically, I want to log the entry and exit of every method of every class in a specific package. This is what I have...
(note: I am using annotation-controllers; I am omitting details not directly-related to aop because my basic setup works fine -- I am only including aop-related details -- let me know if you need to see more)
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;
}
}
}
Here is what I'm getting when HomeController#get() is invoked:
Entering controller.HomeController#get() using arguments: []
In HomeController#get()...
In HomeController#somePrivateMethod()...
In HomeController#somePublicMethod()...
Leaving controller.HomeController#get().
As you can see, the only method that's getting intercepted is HomeController#get(). When #get() calls #somePrivateMethod() or #somePublicMethod(), the interceptor doesn't catch those. I would expect, at the very least, that #somePublicMethod() would also get caught (and since I'm using cglib, I would also expect that #somePrivateMethod() would get caught).
So I guess my question is what do I need to change/add in order to allow (at the very least) all public methods in the controller-package to get caught even when another method in that package called them and was itself caught first???
I hope that makes sense. :D
EDIT(25APR2011 @ 1:13PM)
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>
In Netbean's "Project Properties" under the "Run" tab I added this line to the "VM Options" :
-javaagent:C:\Users\bgresham\Documents\libraries\spring-framework-2.5\dist\weaving\spring-agent.jar
As before, I'm not getting any errors -- I just don't get the "nested"-logging I'm looking for.
???