In my latest project I had a requirement to log the inputs and outputs generated by a method with the same name across multiple objects. This was a little more complicated than the functionality included in the SimpleTraceInterceptor and the DebugInterceptor provided by Spring (http://java.dzone.com/articles/using-spring-aop-trace ) since some processing was involved.

Instead of directly modifying every single one of my classes I decided to take advantage of the support for Aspects that Spring has. There are several sites that describe how to configure an aspect using Spring, including the Spring documentation (http://static.springsource.org/spring/docs/2.5.0/reference/aop.html ). After following those instructions I end up with the following:

  • A Pointcut

A pointcut identifies the point in your classes where you want your aspect to execute. It is formed by 2 parts: the method declaration and the expression. In my case I needed a pointcut related to the execution of my method.

@PointCut("execution(* myMethod(..))")
public void pointCutMyMethod(){
}

This pointcut will work with all the Spring managed beans that have a method called "myMethod".

  • An Advice

This is the action to be taken at a particular pointcut. It can run before, after or around the method execution identified by the pointcut. For my application I was interested in logging the results generated by the method so I used the after returning advice.

@AfterReturning(point = "pointCutMyMethod()", returning = "generatedRs" )
private void logGeneratedReq( JoinPoint joinPoint, Object generatedRs) {
	Log log = LogFactory.getLog(joinPoint.getTarget().getClass());
	log.debug("Method signature: " + joinPoint.getSignature().getName() + 
", object generated: " + genratedRs );
}
  • An entry in the application context for my newly created aspect:

id="myMethodAspect" class="com.mytest.MyMethodAspect"/>

  • An entry in the application context for the definition to enable the support to @AspectJ:

class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />

  • And finally the addition of the following two jars to the application classpath: aspectjweaver.jar and aspectjrt.jar

Everything was going well until I decided to deploy and test my Aspect. After deploying my application with the new aspect I kept getting the following error when my advice was being executed:

The error BeanNotOfRequiredTypeException: Bean named ‘XXXBean" must be a type "type", but it was actually of type [$Proxy151]

After some research I found out that this was related to the proxying mechanism used by my application. Spring supports two different techniques behind the scenes:

  • If the bean classes implement interfaces it will use JDK dynamic proxies
  • If the bean classes do not implement interfaces it will use CGLIB to create a new class on the fly that is a subclass of the target class.

By default the Aspect implementation will assume JDK dynamic proxies which was not the case for my application, hence the errors. This can be resolved by forcing the use of CBLIB proxies by setting the proxyTargetClass property in the definition of the Aspect notation support:

class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator">
 name="proxyTargetClass" value="true"/>
/bean>

After this simple modification the aspect started to work correctly. Hopefully this will make your Aspect development a little easier.