Я пытаюсь использовать 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 в приведенном выше фрагменте.
ЧтоЯ обнаружил, что log.info в циклах класса Aspect покажет, что 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 никогда не выполнялась.
Разрешение:
За комментарий ниже, Пользовательская аннотация нуждается в @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 "";
}
Это работает.