Friday, May 28, 2010

Get a Spring Aspect Working

After some time away from AOP, I've found myself forgetting the bare essentials of getting off the ground - i.e., what's the least I have to do just to prove that my aspect is getting invoked?

Assuming a Spring 3.0 environment, here is the summary:
  1. Create the aspect
  2. Create a Spring context file that declares AOP
  3. Use Spring to instantiate both the aspect and the application object
  4. Run your test case to prove it's working
Here's a bare-bones aspect:

package com.mybiz;
import org.aspectj.lang.annotation.Aspect;

public class MyAspect
    // Flag indicating that a given pointcut was in fact invoked.
    public boolean madeIntercept = false;

    @Pointcut("execution(* com.mybiz.MyApp.myMethod(..))")
    public void myMethodPointcut() {}

    public void doSomething() { madeIntercept = true; }

Here's a simple Spring file, named spring-test-aspect.xml:

<beans xmlns=""

    <context:component-scan base-package="com.mybiz"/>



The aspect will automatically get Spring-managed since it uses the @Component annotation, and component scanning declared above includes its package. Use the same approach with your application object:

package com.mybiz;
public class MyApp
    public void myMethod() {}

Filling in the method is irrelevant; all we're trying to do is prove that if that method is invoked, that the aspect will  intercept the control flow afterwards. Here's a test case that does this for us:

package com.mybiz;

@ContextConfiguration(locations ={"file:spring-test-aspect.xml"})
public class MyAspectTest extends AbstractTestNGSpringContextTests
    private MyAspect myAspect;

    private MyApp myApp;

    public void init() { assert myAspect != null; assert myApp != null; }

    public void confirmInterception() 
        assert !myAspect.intercepted();
        assert myAspect.intercepted();

There's the proof-of-concept; from here, you'd add real functionality to your application class and decorate that functionality with the aspect. I should offer a fair warning: the above snippets have not been actually compiled and run, rather simply copy-pasted with various names changed to be more general purpose (as such, it might not be totally correct). So, if you bump into any problems - you have my apologies, but I'm sure the problems will be trivial.