@AspectJ类级别注释Annotation作为方法参数的建议

我如何获得批注作为为类级批注定义的建议的参数传递? 可能吗?

从这里的帖子中,我可以得到标识所有公共方法的标记为特定注释的标记。 我也能够得到建议。 但是,我不知道如何在上面的情况下获取作为参数传递的注释变量。

对于方法级注释,我能够获得切入点和建议,我可以将注释作为参数传递,但我不知道如何为类级注释实现相同。

下面的代码有效,但我需要在下面的程序中获得注释作为参数“ LogExecutionTimeByClass ”的参数,我无法得到适当的建议或切入点。

注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
String level();
}

方面:

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 to match all the public methods.
    */
    @Pointcut("execution(public * *(..))")
    public void publicMethod() {}

    /*
     * Advice for the public methods that are marked with Annotation "LogExecutionTime" and it works as expected no issue.
    */ 
    @Around("publicMethod() && @annotation(annotation) ")
    public Object LogExecutionTimeByMethod(final ProceedingJoinPoint joinPoint,final LogExecutionTime annotation) throws Throwable 
    {
        System.out.println("Invoking the method " +joinPoint.getSignature() +" by LogExecutionTimeByMethod Advice");
        return joinPoint.proceed();
    }


    /*
     * Pointcut to match all the public methods that are defined under the Class marked with Annotation LogExecutionTime.
    */
    @Pointcut("within(@LogExecutionTime *)")
    public void beanAnnotatedWithMonitor() {}

    @Pointcut("publicMethod() && beanAnnotatedWithMonitor()")
    public void publicMethodInsideAClassMarkedWithAtMonitor() {}

    /*
     * Below Advice works but I need the LogExecutionTime annotation as an argument to below method. (similar to the advice "LogExecutionTimeByMethod" 
     * defined above)
    */
    @Around("publicMethodInsideAClassMarkedWithAtMonitor()")
    public Object LogExecutionTimeByClass(final ProceedingJoinPoint joinPoint) throws Throwable 
    {
        System.out.println("Invoking the method " +joinPoint.getSignature() +" by  LogExecutionTimeByClass Advice");
        //System.out.println("Invoked by " + annotation.value()); //Need the Annotation Variable here as well...
        return joinPoint.proceed();
    }

/*
    */
}

注释类:

@LogExecutionTime(level="Class_Level_Invocation")
public class Operator {

    @LogExecutionTime(level="Method_Level_Invocation")
    public void operate()  throws InterruptedException {
        Thread.sleep(1000);
    }

    public void operate1() throws InterruptedException {
        Thread.sleep(1000);
    }
}

主要计划:

public class AspectJMain {
     public static void main(String[] args) throws InterruptedException {
            Operator op = new Operator();
            op.operate();
            op.operate1();
        }
}

输出:

Invoking the method void Operator.operate() by LogExecutionTimeByMethod Advice
Invoking the method void Operator.operate() by  LogExecutionTimeByClass Advice
Invoking the method void Operator.operate1() by  LogExecutionTimeByClass Advice

请注意,使用Spring不是一种选择。 我必须使用AspectJ编译器。 我编译我的类并将它们打包为jar,并使用ApsectJ编译器使用下面的命令编织该方面。

ajc -inpath core.jar -outjar .. lib core_woven.jar -1.5

任何指针都会有帮助。


解决方案其实很简单。 我使用本地AspectJ风格编写代码,为了清晰起见,我更喜欢它。 您将很容易将其调整为@AspectJ注释样式:

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());
    }
}

输出如下:

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

如你看到的,

  • 不需要around()建议, before()就足够了,除非你想操纵任何参数或者阻止捕获的方法执行,
  • 如果您只使用正确的语法,则可以通过@annotation()@within()将有问题的注释绑定到命名参数。
  • 请享用! :-)


    更新:为方便起见,这里是方面的@AspectJ版本,因为您似乎遇到了使用本机语法修改我的解决方案的问题:

    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();
        }
    }
    

    结果将与我的原始版本相同。

    链接地址: http://www.djcxy.com/p/77255.html

    上一篇: @AspectJ Class level Annotation Advice with Annotation as method argument

    下一篇: AspectJ aspect not weaving Spring MVC methods with @RequestMapping annotation