我需要在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)
然而,只有公共方法被截获。
答案 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 * *(..))")