我正在尝试使用Spring AOP在我的控制器类上捕获一些日志数据。
我为此使用了自定义注释,但似乎失败了。
@Around("execution(* path.to.package.endpoints.*Controller.*(..))")
private Object controllerMethodTimer(ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Annotation[][] annotations = signature.getMethod().getParameterAnnotations();
String[] parameterNames = signature.getParameterNames();
Object[] parameterValues = joinPoint.getArgs();
Map<String, String> parameters = new HashMap<>();
for (Integer i = 0; i < parameterNames.length; i++) {
for (Annotation annotation : annotations[i]) {
if (Loggable.class.isInstance(annotation)) {
Loggable loggable = (Loggable) annotation;
if (loggable.name() != ""){
parameters.put(loggable.name(), parameterValues[i].toString());
} else {
parameters.put(parameterNames[i], parameterValues[i].toString());
}
}
}
}
//do stuff
//when printing the parameters map, it is always blank
}
可记录类:
public @interface Loggable {
String name() default "";
}
有问题的方法
public ResponseEntity<Object> defaultLens(RestContext restContext,
@Loggable @RequestBody LensRequest parameters,
@RequestParam(value = "plugins", required = false) String commaDelimitedPluginNames) {
//some stuff
}
我已经尝试在上述代码段中交换Loggable / RequestBody的位置。
我发现的是,Aspect类循环中的log.info将显示正在查找RequestBody并将其放置在注释数组中,但未显示Loggable。
先前使用的代码迭代:
for (Integer i = 0; i < parameterNames.length; i++) {
Loggable annotation = AnnotationUtils.findAnnotation(parameterValues[i].getClass(), Loggable.class);
if (annotation != null){
if (annotation.name() != ""){
parameters.put(annotation.name(), parameterValues[i].toString());
} else {
parameters.put(parameterNames[i], parameterValues[i].toString());
}
}
}
发现Loggable始终为null,并且循环的!= null部分从未被命中。
解决方案:
以下每个注释中,自定义注释需要@Retention(RetentionPolicy.RUNTIME)
新的Loggable类如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Loggable {
String name() default "";
}
这正在工作。