@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