问题
I'm using spring aop with groovy and have a monitoring aspect that should log each method's execution time. The problem is groovy calls are not the same as java calls so the following code always prints "getMetaClass()" as method name.
@Before("execution(* mypackage.MyService.*(..))")
void beforeMethod(JoinPoint joinPoint) {
logger.info(joinPoint.signature.name + " called")
}
I see two ways to solve the problem:
- Find the actual method from the groovy call
- Use some other way to get the called method (instead of injecting jointPoint argument)
Any ideas?
回答1:
For Option 1:
Try adding a !getMetaClass()
Pointcut
to your @Aspect
class like this:
@Pointcut("!execution(* mypackage.MyService.*.getMetaClass(..))")
public void noMetaClassMethods() {}
As well as making your original execution matcher into a Pointcut
:
@Pointcut("execution(* mypackage.MyService.*(..))")
public void myServices() {}
Then combine those two in your @Before
like this:
@Before("myServices() && noMetaClassMethods()")
void beforeMethod(JoinPoint joinPoint) {
logger.info(joinPoint.signature.name + " called")
}
It should give you what you're looking for.
For Option 2: You could add a name attribute to your annotation on the target method:
@Timed(name="methodIWantToTime")
def methodIWantTime(..)
Then just include the annotation as an argument your method in your Aspect
class:
@Around(value="@annotation(timed)")
def timeMethod(ProceedingJoinPoint proceedingJointPoint, Timed timed) {
println timed.name()
proceedingJointPoint.proceed()
}
and peel it off of that.
来源:https://stackoverflow.com/questions/28474278/spring-aop-with-groovy-get-called-method