Java @带有注释作为方法参数的AspectJ类级注释建议

Java @带有注释作为方法参数的AspectJ类级注释建议,java,aop,aspectj,Java,Aop,Aspectj,如何将注释作为为定义的通知的参数传递 类级注释?可能吗 从这篇文章中,我可以得到一个切点,它标识了类中所有由特定注释标记的公共方法。我也能应用这些建议。但是,我不知道在上述情况下如何将注释变量作为参数传递 对于方法级注释,我能够获得切入点和建议,在这些切入点和建议中,我可以将注释作为参数传递,但我不知道如何实现类级注释的相同功能 下面的代码可以工作,但我需要获得注释作为下面程序中建议“LogExecutionTimeByClass”的参数,我无法获得相应的建议或切入点 注释: import ja

如何将注释作为为定义的通知的参数传递 类级注释?可能吗

从这篇文章中,我可以得到一个切点,它标识了类中所有由特定注释标记的公共方法。我也能应用这些建议。但是,我不知道在上述情况下如何将注释变量作为参数传递

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

下面的代码可以工作,但我需要获得注释作为下面程序中建议“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\u woven.jar-1.5


任何指针都会有帮助。

解决方案实际上非常简单。我正在用原生AspectJ风格编写代码,为了清晰起见,我更喜欢它。您可以轻松地将其调整为@AspectJ注释样式:

公共方面LogTimeAspect{
切入点publicMethod():执行(public**(..);
之前(LogExecutionTime logAnn):publicMethod()&&&@注释(logAnn){
System.out.println(thisJoinPointStaticPart+“->”+logAnn.level());
}
在(LogExecutionTime logAnn)之前:publicMethod()&&@在(logAnn)之内{
System.out.println(thisJoinPointStaticPart+“->”+logAnn.level());
}
}
结果如下:

执行(void Operator.operate())->方法级调用
执行(void Operator.operate())->类级调用
执行(void Operator.operate1())->类级调用
如你所见

  • 无需使用
    around()
    建议,
    before()
    就足够了,除非您想操作任何参数或阻止捕获的方法执行
  • 只要使用正确的语法,就可以通过
    @annotation()
    @within()
    将有问题的注释绑定到命名参数
享受吧<代码>:-)


更新:为了方便您,这里是该方面的@AspectJ版本,因为您似乎无法从本机语法调整我的解决方案:

import org.aspectj.lang.ProceedingJoinPoint;
导入org.aspectj.lang.annotation.Around;
导入org.aspectj.lang.annotation.Aspect;
导入org.aspectj.lang.annotation.Pointcut;
@面貌
公共类LogTimeAspect{
@切入点(“执行(公共**(…)”)
public void publicMethod(){}
@周围(“publicMethod()&&&@annotation(logAnn)”)
公共对象LogExecutionTimeByMethod(ProceedingJoinPoint,LogExecutionTime logAnn)抛出Throwable{
System.out.println(joinPoint+“->”+logAnn.level());
返回joinPoint.procedure();
}
@周围(“publicMethod()&&&@in(logAnn)”)
公共对象LogExecutionTimeByClass(ProceedingJoinPoint,LogExecutionTime logAnn)抛出Throwable{
System.out.println(joinPoint+“->”+logAnn.level());
返回joinPoint.procedure();
}
}

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

谢谢。让我试试看。之所以选择Around是为了获得方法的执行时间。我尝试了通过point cut works@Pointcut(“publicMethod()&&beanAnnotatedWithMonitor()&&annotation(annotation)”)内但无法通过point cut works传入注释参数。您确实不需要
beanAnnotatedWithMonitor()
,请参阅我上面的更新。