Spring 具有 groovy 的 AOP:调用方法
Spring AOP with groovy: get called method
我正在使用 spring aop 和 groovy 并且有一个监控方面应该记录每个方法的执行时间。问题是 groovy 调用与 java 调用不同,因此以下代码始终打印 "getMetaClass()" 作为方法名称。
@Before("execution(* mypackage.MyService.*(..))")
void beforeMethod(JoinPoint joinPoint) {
logger.info(joinPoint.signature.name + " called")
}
我看到两种解决问题的方法:
- 从 groovy 调用中找到实际方法
- 使用其他方式获取调用的方法(而不是注入 jointPoint 参数)
有什么想法吗?
对于选项 1:
尝试将 !getMetaClass()
Pointcut
添加到您的 @Aspect
class 中,如下所示:
@Pointcut("!execution(* mypackage.MyService.*.getMetaClass(..))")
public void noMetaClassMethods() {}
以及将您的原始执行匹配器变成 Pointcut
:
@Pointcut("execution(* mypackage.MyService.*(..))")
public void myServices() {}
然后像这样在 @Before
中组合这两个:
@Before("myServices() && noMetaClassMethods()")
void beforeMethod(JoinPoint joinPoint) {
logger.info(joinPoint.signature.name + " called")
}
它应该能满足您的需求。
对于选项 2:您可以将名称属性添加到目标方法的注释中:
@Timed(name="methodIWantToTime")
def methodIWantTime(..)
然后将注释作为参数包含在您的方法中 Aspect
class:
@Around(value="@annotation(timed)")
def timeMethod(ProceedingJoinPoint proceedingJointPoint, Timed timed) {
println timed.name()
proceedingJointPoint.proceed()
}
然后把它剥下来。
我正在使用 spring aop 和 groovy 并且有一个监控方面应该记录每个方法的执行时间。问题是 groovy 调用与 java 调用不同,因此以下代码始终打印 "getMetaClass()" 作为方法名称。
@Before("execution(* mypackage.MyService.*(..))")
void beforeMethod(JoinPoint joinPoint) {
logger.info(joinPoint.signature.name + " called")
}
我看到两种解决问题的方法:
- 从 groovy 调用中找到实际方法
- 使用其他方式获取调用的方法(而不是注入 jointPoint 参数)
有什么想法吗?
对于选项 1:
尝试将 !getMetaClass()
Pointcut
添加到您的 @Aspect
class 中,如下所示:
@Pointcut("!execution(* mypackage.MyService.*.getMetaClass(..))")
public void noMetaClassMethods() {}
以及将您的原始执行匹配器变成 Pointcut
:
@Pointcut("execution(* mypackage.MyService.*(..))")
public void myServices() {}
然后像这样在 @Before
中组合这两个:
@Before("myServices() && noMetaClassMethods()")
void beforeMethod(JoinPoint joinPoint) {
logger.info(joinPoint.signature.name + " called")
}
它应该能满足您的需求。
对于选项 2:您可以将名称属性添加到目标方法的注释中:
@Timed(name="methodIWantToTime")
def methodIWantTime(..)
然后将注释作为参数包含在您的方法中 Aspect
class:
@Around(value="@annotation(timed)")
def timeMethod(ProceedingJoinPoint proceedingJointPoint, Timed timed) {
println timed.name()
proceedingJointPoint.proceed()
}
然后把它剥下来。