在Grails中使用AOP不适用于服务 [英] Using AOP in Grails is not working for service

查看:116
本文介绍了在Grails中使用AOP不适用于服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用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){
在方法之前:beforeMethod,
pointcut:执行(* 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(JoinPoi nt jp){
println' - Before Method。'
}

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


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

  package com.test $ b $ class DemoService {
def serviceMethod(){
println'在DemoService.serviceMethod()'
}
}

并创建一个控制器来调用服务进行测试

  package com.test $ b $ class DemoController {
def index() {
println'DemoController.index()'
def demoService = new DemoService()
demoService.serviceMethod()

'Hello World'
}
}

最后,我通过url测试aop:

  http:// myhost:8080 / grails-spring-aop / demo / index 

并且aop不被调用。以下是结果:

  |服务器运行。浏览到http:// myhost:8080 / grails-spring-aop / 
在DemoController.index()
中DemoService.serviceMethod()

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

  static transactional = false 

而且,它仍然不适合我。



任何人都知道如何解决这个问题,或者这是不可能的。
或者我做错了什么。



谢谢。

解决方案

您需要在控制器中注入服务(spring bean),而不是创建它的一个实例。

  package com .test 
class DemoController {
def demoService // Autowired,不需要在resources.groovy中指定
$ b def index(){
println'在DemoController.index ()'
demoService.serviceMethod()

render'Hello World'
}
}

此外,可以根据以下方面进行注释:

 包com.test.aop.aspect 

@Aspect
类LoggerAspect {

//更通用的建议如下
// @ Before(execution(* com.test。*。*(..)))
@Before(com.test.DemoService.serviceMethod())
def beforeMethod(){
println' - Before Method。'
}

//更通用的建议如下
// @ 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)
}
}
}


I use Grails 2.2.3 and type following codes in 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())"
            }
        }
    }
}

then, create an aspect class under 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.'
    }
}

And create a service class under grails-app/services/com/test

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

And create a controller to call service for testing

package com.test
class DemoController {
    def index() {
        println 'In DemoController.index()'
        def demoService = new DemoService()
        demoService.serviceMethod()

         render 'Hello World'
    }
}

Finally, I test the aop through url:

http://myhost:8080/grails-spring-aop/demo/index

and the aop is not invoked. Following is the result:

| Server running. Browse to http://myhost:8080/grails-spring-aop/
In DemoController.index()
In DemoService.serviceMethod()

I add the following line to the service class:

static transactional = false

And, it's still not working for me.

Anyone an idea how this can be solved or is this not possible. Or I do the something wrong.

Thanks.

解决方案

You need to inject the service (spring bean) in the controller instead of creating an instance of it.

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'
    }
}

Moreover, the aspect can be made annotation based as below:

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.'
    }
}

And resources.groovy could become:

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") 
        }
    }
}

这篇关于在Grails中使用AOP不适用于服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆