Grails& AspectJ:私有方法的建议不起作用

时间:2015-01-22 22:43:32

标签: grails aspectj spring-aop

我需要在Grails服务中拦截对私有方法的调用。以下方面适用于任何带注释的公共方法,但是当注释处于PRIVATE方法时没有任何反应。

import exceptions.DwcpExeption
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component

@Aspect
@Component
public class LoggerInterceptor {
    private static Logger log = LoggerFactory.getLogger(LoggerInterceptor.class);
    @Around("@annotation(newAnnotation)")
    public Object aroundEvents(ProceedingJoinPoint proceedingJoinPoint, NewAnnotation newAnnotation) {
        log.info newAnnotation.value()
        String logMessage = String.format("%s.%s(%s)",
                proceedingJoinPoint.getTarget().getClass().getName(),
                proceedingJoinPoint.getSignature().getName(),
                Arrays.toString(proceedingJoinPoint.getArgs()));
        log.info "*Entering $logMessage"
        def result
        try {
            result = proceedingJoinPoint.proceed()
        catch (ex) {
            log.error '', ex
        }
        log.info "*Exiting $logMessage. Result: $result"
        return result
    }
}

也许问题出在配置中?我在applicationContext.xml中尝试过 <aop:aspectj-autoproxy proxy-target-class="true"/> 并在resources.groovy aop.config("proxy-target-class": true)

然而,只有公共方法被截获。

2 个答案:

答案 0 :(得分:4)

Spring AOP是一个基于代理的&#34; AOP lite&#34;与AspectJ相比的方法。它仅适用于Spring组件,仅适用于公共,非静态方法。这也在Spring AOP documentation中解释如下:

  

由于Spring的AOP框架基于代理的特性,根据定义,受保护的方法既不是针对JDK代理(这不适用),也不针对CGLIB代理(技术上可行但不是推荐用于AOP目的)。因此,任何给定的切入点都只能与公共方法匹配!

     

如果您的拦截需要包括受保护/私有方法甚至构造函数,请考虑使用Spring驱动的本机AspectJ编织而不是Spring的基于代理的AOP框架。这构成了具有不同特征的不同AOP使用模式,因此在做出决定之前一定要先熟悉编织。

底线:请切换到AspectJ,可以通过LTW(加载时编织)轻松集成到Spring应用程序中,如Section 9.8, “Using AspectJ with Spring applications”中所述。

答案 1 :(得分:2)

如果您没有指定范围,则默认为公开范围。为私有方法添加切入点:

@Around("@annotation(newAnnotation) && execution(private * *(..))")