在Grails中使用AOP无法为服务工作

3

我使用Grails 2.2.3,将下面的代码添加到grails-app/conf/spring/resources.groovy中:

beans = {
    xmlns aop:"http://www.springframework.org/schema/aop"
    loggerAspect(com.test.aop.aspect.LoggerAspect)
    aop{
        config("proxy-target-class": true) {
            aspect(id: "beforeService", ref: "loggerAspect") {
                before method: "beforeMethod", 
                pointcut: "execution(* com.test.DemoService.serviceMethod())"
            }
            aspect(id: "afterService", ref: "loggerAspect") {
                after method: "afterMethod", 
                pointcut: "execution(* com.test.DemoService.serviceMethod())"
            }
        }
    }
}

接下来,在src/groovy/com/test/aop/aspect下创建一个切面类。

package com.test.aop.aspect
class LoggerAspect {
    def beforeMethod(JoinPoint jp){
        println '-- Before Method.'
    }

    def afterMethod(JoinPoint jp){
        println '-- After Method.'
    }
}

在grails-app/services/com/test下创建一个服务类

package com.test
class DemoService {
    def serviceMethod() {
        println 'In DemoService.serviceMethod()'
    }
}

创建一个控制器以调用服务进行测试。
package com.test
class DemoController {
    def index() {
        println 'In DemoController.index()'
        def demoService = new DemoService()
        demoService.serviceMethod()

         render 'Hello World'
    }
}

最后,我通过url测试了aop:
http://myhost:8080/grails-spring-aop/demo/index

而aop未被调用。以下是结果:
| Server running. Browse to http://myhost:8080/grails-spring-aop/
In DemoController.index()
In DemoService.serviceMethod()

我将以下行添加到服务类中:

我将以下行添加到服务类中:

static transactional = false

还有,这对我仍然没有起作用。

有人有想法如何解决这个问题吗?或者这不可能实现。 或者是我做错了什么。

谢谢。

1个回答

11
你需要在控制器中注入服务(Spring Bean),而不是创建其实例。
package com.test
class DemoController {
    def demoService //Autowired, not required to specify in resources.groovy

    def index() {
        println 'In DemoController.index()'
        demoService.serviceMethod()

        render 'Hello World'
    }
}

此外,该方面可以基于注释进行如下操作:
package com.test.aop.aspect

@Aspect
class LoggerAspect {

    //A more generic advice would be as below
    //@Before("execution(* com.test.*.*(..))")
    @Before("com.test.DemoService.serviceMethod()")
    def beforeMethod(){
        println '-- Before Method.'
    }

    //A more generic advice would be as below
    //@Around("execution(* com.test.*.*(..))")
    @After("com.test.DemoService.serviceMethod()")
    def afterMethod(){
        println '-- After Method.'
    }
}

而resources.groovy可以变成:

beans = {
    loggerAspect(com.test.aop.aspect.LoggerAspect)

    xmlns aop:"http://www.springframework.org/schema/aop"
    aop{
        config("proxy-target-class": true) {
            aspect(id: "loggerAspectService", ref: "loggerAspect") 
        }
    }
}

除非您允许Spring容器解析依赖项,否则该方面将无法在切入点之前、之后或周围执行建议。 - dmahapatro
@Thomas.Yu 很高兴听到它能够正常工作。我添加了更多信息,以便可以基于注释编写Aspect,从而最小化bean依赖关系。 - dmahapatro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接