Spring AOP - Пользовательская аннотация не появляется в JoinPoint - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь использовать 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 "";
}

Это работает.

...