我有一个可以放在类或方法上的注释:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface TestAspectAnnotation {
String[] tags() default {};
}
我想有一个建议方法来处理类级别和方法级别的用法:
@Around(value = "@annotation(annotation) || @within(annotation)", argNames = "pjp,annotation")
public Object testAdvice(ProceedingJoinPoint pjp,
TestAspectAnnotation annotation) throws Throwable {
String[] tags = annotation.tags();
Stopwatch stopwatch = Stopwatch.createStarted();
Object proceed = pjp.proceed();
stopwatch.stop();
long executionTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);
sendMetrics(tags, executionTime);
return proceed;
}
当我用TestAspectAnnotation(tags="foo")
注释课程时,这很好用。
但是,如果我注释方法,则annotation
参数将为null
。
[有趣的是,如果我颠倒切入点指示符("@within(annotation) || @annotation(annotation)"
)的顺序,那么我将遇到一个相反的问题:方法级注释会正常工作,但类级注释会为[ C0]参数。
有没有一种方法可以在类级别和方法级别使用单个切入点和建议来支持注释?
有没有办法提供我最近遇到了类似的问题,并尝试了各种选择,但无济于事。我最终将“或”切入点拆分为两个单独的切入点,并从两个建议中调用了相同的方法。单个切入点和建议
我已经建立了一个小型演示项目,以说明我已经建立的可行解决方案。希望对您有所帮助:
null
annotation
@Component
@Aspect
public class SomeAspect {
@Around(value = "@within(annotation)", argNames = "pjp,annotation")
public Object methodAdvice(ProceedingJoinPoint pjp, SomeAnnotation annotation) throws Throwable {
return logTags(pjp, annotation);
}
@Around(value = "@annotation(annotation)", argNames = "pjp,annotation")
public Object classAdvice(ProceedingJoinPoint pjp, SomeAnnotation annotation) throws Throwable {
return logTags(pjp, annotation);
}
private Object logTags(ProceedingJoinPoint pjp, SomeAnnotation annotation) throws Throwable {
Stream.of(annotation.tags()).forEach(System.out::println);
return pjp.proceed();
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface SomeAnnotation {
String[] tags() default {};
}