Spring AOP: Logging and Nested Methods

I wrote a simple Spring2.5 application to demonstrate / test AOP; in particular, I want to register a record and exit from each method of each class in a specific package. This is what I have ...

(note: I use annotation controllers, I do not specify details that are not directly related to aop, because my basic setup works fine - I only include aup-related information - 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 get when calling HomeController # get ():

 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 way to intercept is HomeController # get (). When #get () calls #somePrivateMethod () or #somePublicMethod (), the interceptor does not detect them. I would expect at least that #somePublicMethod () would also be caught (and since I use cglib, I would also expect #somePrivateMethod () to be caught).

So, I think, my question is what I need to change / add to allow (at least) all public methods in the controller package to be caught, even when another method in this package called them and the first one was caught ?? ?

Hope this makes sense. : D


EDIT (25APR2011 @ 13: 13)

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 the "Netbean Project Properties" on the "Run" tab, I added this line to the "VM Settings" :

 -javaagent:C:\Users\bgresham\Documents\libraries\spring-framework-2.5\dist\weaving\spring-agent.jar 

As before, I do not get any errors - I just do not get the "attached" files that I am looking for.

???

+6
source share
2 answers

If you use Spring AOP, you should call a method that has the aspect applied to it using the link returned by Spring, not through this , and I don't think you can apply pointcuts to private methods (maybe it’s wrong in this last part). This is because Spring AOP applies pointcuts through a proxy object, rather than by rewriting the class (which is what AspectJ does). The advantage of such a hard restriction is that it is much easier to make it work in containers (I know from experience that Spring AOP works fine inside Tomcat), because there is no conflict with which bits are connected there.

The best way to do this is to break the class definition so that you never call the method through this , but if this is not possible, you can always try giving the bean a Spring link yourself:

 private HomeController self; @Required public void setSelf(HomeController self) { this.self = self; } public ModelAndView get() { System.out.println("In HomeController#get()..."); self.somePrivateMethod(); self.somePublicMethod(); return new ModelAndView( "home" ); } 

(This is pretty neat; self is a keyword in several languages, but not Java, so it's relatively easy to remember what you use it for.)

+5
source

You are using spring aop to support the aspect. spring aop will only work on spring beans. Thus, pointcut does not work on the actual instance of the class, that is, when the controller calls any of its public or private method. To register all methods in the controller, you need to use AspectJ to support aop, including either load time or compile time of all classes that you want to intercept. Edit:

To download the boot time you will need the following:

aop.xml

 <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"> <aspectj> <weaver options="-Xset:weaveJavaxPackages=true -verbose -showWeaveInfo -debug"> <include within="*"/> </weaver> <aspects> <!-- weave in just this aspect --> <aspect name="your.logger.impl.LoggingImpl"/> </aspects> </aspectj> 

This implies weaving in all of your files ("inside = *", change as you wish) with the specified aspect / s. At boot time, you should see detailed information about weaving classes.

Configurations in spring configurations:

 <context:load-time-weaver aspectj-weaving="autodetect" weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/> 

Please note that the weaving class should be in the path to the server library, and not in your application path.

The above configurations should do what you are looking for.

+3
source

Source: https://habr.com/ru/post/886631/


All Articles