@AspectJ Class level Annotation Advice with Annotation as method argument

前端 未结 1 647
挽巷
挽巷 2021-02-15 14:40

How can I get the annotation to be passed as the argument for the Advice defined for class-level annotation? Is it possible?

From the post here I am able to get the poi

1条回答
  •  旧巷少年郎
    2021-02-15 14:57

    The solution is actually quite simple. I am writing my code in native AspectJ style, I prefer it for clarity. You will be easily able to adjust it to @AspectJ annotation style:

    public aspect LogTimeAspect {
        pointcut publicMethod() : execution(public * *(..));
    
        before(LogExecutionTime logAnn) : publicMethod() && @annotation(logAnn) {
            System.out.println(thisJoinPointStaticPart + " -> " + logAnn.level());
        }
    
        before(LogExecutionTime logAnn) : publicMethod() && @within(logAnn) {
            System.out.println(thisJoinPointStaticPart + " -> " + logAnn.level());
        }
    }
    

    The output is as follows:

    execution(void Operator.operate()) -> Method_Level_Invocation
    execution(void Operator.operate()) -> Class_Level_Invocation
    execution(void Operator.operate1()) -> Class_Level_Invocation
    

    As you can see,

    • there is no need for around() advice, before() is sufficient unless you want to manipulate any parameters or block the captured method executions,
    • you can bind the annotations in question via @annotation() or @within() to named parameters if you just use the correct syntax.

    Enjoy! :-)


    Update: Here is the @AspectJ version of the aspect for your convenience and because you seemed to have problems adapting my solution from the native syntax:

    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class LogTimeAspect {
        @Pointcut("execution(public * *(..))")
        public void publicMethod() {}
    
        @Around("publicMethod() && @annotation(logAnn)")
        public Object LogExecutionTimeByMethod(ProceedingJoinPoint joinPoint, LogExecutionTime logAnn) throws Throwable {
            System.out.println(joinPoint + " -> " + logAnn.level());
            return joinPoint.proceed();
        }
    
        @Around("publicMethod() && @within(logAnn)")
        public Object LogExecutionTimeByClass(ProceedingJoinPoint joinPoint, LogExecutionTime logAnn) throws Throwable {
            System.out.println(joinPoint + " -> " + logAnn.level());
            return joinPoint.proceed();
        }
    }
    

    The results will be identical to my original version.

    0 讨论(0)
提交回复
热议问题