2013-07-01 9 views
5

Ich möchte eine benutzerdefinierte Protokollierung in meinem Grails-Projekt erstellen.AOP mit Grails

Mein 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(); 
    } 
} 

Frühling config:

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

auditLogInterceptor(AuditLogInterceptor) {} 

Das Ergebnis:

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

Ich würde gerne die Annotation Feuer für Methode 2 auch sehen. Was vermisse ich?

Antwort

8

Dies geschieht, weil das interne Verfahren in der Serviceklasse zur Selbst Anrufe sind nicht auf der Proxy-Instanz der Klasse service getan. Wenn Sie die Service-Bean aus dem Anwendungskontext abrufen und versuchen, method2() aufzurufen, sollten Sie die aspect hören die advice hören.

class MyService{ 
    static transactional = false 
    def grailsApplication 

    @AuditLog 
    def method1() { 
     println "method1 called" 
     grailsApplication.mainContext.myService.method2() 
     //method2() 
    } 
    @AuditLog 
    def method2() { 
     println "method2 called" 
    } 
} 
+0

Schöne Einsicht! Ich denke, es wäre großartig, wenn Grails Magie bietet, um Aufrufe an Methoden in derselben Serviceklasse an die Proxy-Klasse zu delegieren. –