Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AOP with Grails

I want to create a custom logging annotation in my Grails project.

My code:

class MyService{
    @AuditLog
    def method1() {
        println "method1 called"
        method2()
    }
    @AuditLog
    def method2() {
        println "method2 called"
    }
}

Interceptor:

class AuditLogInterceptor implements MethodInterceptor {
    @Override
    Object invoke(MethodInvocation methodInvocation) throws Throwable {
        println "${methodInvocation.method}"
        return methodInvocation.proceed();
    }
}

Spring config:

aop {
    config("proxy-target-class": true) {
        pointcut(id: "auditLogInterceptorPointcut", expression: "@annotation(xxx.log.AuditLog)")
        advisor('pointcut-ref': "auditLogInterceptorPointcut", 'advice-ref': "auditLogInterceptor")
    }
}

auditLogInterceptor(AuditLogInterceptor) {}

The result:

public java.lang.Object xxx.MyService.method1()
method1 called
method2 called

I would like to see the annotation fire for method 2 as well. What am I missing?

like image 482
Jakabfi Attila Avatar asked Jul 01 '13 17:07

Jakabfi Attila


1 Answers

This happens because the internal method calls in the service class to self are not done on the proxied instance of the service class. If you fetch the service bean from the application context and try to call method2() you should see the aspect listening to the advice.

class MyService{
    static transactional = false
    def grailsApplication

    @AuditLog
    def method1() {
        println "method1 called"
        grailsApplication.mainContext.myService.method2()
        //method2()
    }
    @AuditLog
    def method2() {
        println "method2 called"
    }
}
like image 194
dmahapatro Avatar answered Oct 18 '22 11:10

dmahapatro