Sunday, April 15, 2007

Groovy and AOP Metaclass

I've recently found John McClean's last year article about AspectJ-like AOP model implemented in Groovy. In its comments, his readers posted that he should have a custom MetaClass to support his approach. I'm sure he probably did it because he's going to talk about AOP in Groovy at Grails Exchange conference this May. However based on his implementation, I've done the similar MetaClass as well, as I need some kind of AOP facility to support my research.

Probably after the Grails Exchange event, I can see his AOP code somewhere.

Here's my implementation:

package org.plaop;

import groovy.lang.DelegatingMetaClass

public class AOPSupportMetaClass extends DelegatingMetaClass {

def after = [:]
def before = [:]
def around = [:]

public AOPSupportMetaClass(MetaClass delegate) {

public Object getProperty(Object object, String prop) {
if(prop == 'around') return this.around else
if(prop == 'before') return this.before else
if(prop == 'after') return this.after else
return super.getProperty(object, prop)

public Object invokeMethod(Object arg0, String name, Object[] args) {
if(before[name]!=null) {

def inv = new InvocationContext(methodName: name, args: args, called: arg0)
inv.proceed = { arglist ->
super.invokeMethod(arg0, name, arglist)

def result = null
if(around[name]!=null) {
result = around[name](inv)
} else {
result = super.invokeMethod(arg0, name, args)

inv.proceed = null

if(after[name]!=null) {
return result

This is how to use it:

void testBasicAround() {
def mcr = InvokerHelper.getInstance().metaRegistry
AOPSupportMetaClass amc = new AOPSupportMetaClass(
mcr.setMetaClass(TestObject.class, amc)

def t = new TestObject()
t.around['save'] = { inv ->
inv.args[0] = inv.args[0] + '.'

The big bug here is that this MetaClass hasn't yet supported per class weaving model. But it's not that hard to implement. John's article really realised me the power of Groovy MOP from AOP perspective.

1 comment:

Bertrand said...

Hence the class InvocationContext come from (I can't compile AOPSupportMetaClass)?
Also, in the invokeMethod, I see that the reference inv is used before its affectation.