Spring AOP: как получить аннотации рекомендуемого метода

Я хотел бы реализовать декларативную безопасность с Spring / AOP и аннотациями. Как вы видите в следующем примере кода, у меня есть ограниченные аннотации с параметром "allowedRoles" для определения того, кому разрешено выполнять рекомендуемый метод.

    @Restricted(allowedRoles="jira-administrators")
        public void setPassword(...) throws UserMgmtException {             
               // set password code
               ...
        }

теперь проблема в том, что в моем совете у меня нет доступа к определенным аннотациям:

public Object checkPermission(ProceedingJoinPoint pjp) throws Throwable {

    Signature signature = pjp.getSignature();
    System.out.println("Allowed:" + rolesAllowedForJoinPoint(pjp));
            ...
}

private Restricted rolesAllowedForJoinPoint(ProceedingJoinPoint thisJoinPoint)
        {
            MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
            Method targetMethod = methodSignature.getMethod();

            return targetMethod.getAnnotation(Restricted.class);
        }

метод выше всегда возвращает null (аннотации не найдены вообще). Есть ли простое решение это?

Я читал что-то об использовании агента AspectJ, но я бы предпочел не использовать этот агент.

5 ответов


предполагаю @Restricted ваша аннотация. Если это так, убедитесь, что у вас есть:

@Retention(RetentionPolicy.RUNTIME)

в определении аннотации. Это означает, что аннотация сохраняется во время выполнения.


для тех, у кого все еще есть проблемы после изменение сохранения аннотаций во время выполнения, у вас может возникнуть та же проблема, что и у меня: getMethod() возвращает метод интерфейса вместо реализующего класса. Итак, если у вас есть ваши аннотации в классе, то, естественно, getAnnotations() на методе интерфейса возвращает null.

следующее решение решило эту проблему:

final String methodName = pjp.getSignature().getName();
final MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
Method method = methodSignature.getMethod();
if (method.getDeclaringClass().isInterface()) {
    method = pjp.getTarget().getClass().getDeclaredMethod(methodName, method.getParameterTypes());    
}

и если вам нравится, у вас есть возможность регулировать интерфейс аннотации здесь.

еще несколько комментариев доступны здесь: получение экземпляра метода шаблона из ProceedingJoinPoint

Олег


даже после изменения политики хранения, как Божо упомянул этот вызов, чтобы получить аннотацию возвращает null:

targetMethod.getAnnotation(Restricted.class);

Я нашел, что вы должны связать аннотацию. Учитывая, что интерфейс объявлен следующим образом:

 @Retention(RetentionPolicy.RUNTIME)
 public @interface Restricted {
     String[] allowedRoles();
  }

совет должен быть объявлен следующим образом:

       @Before("@annotation( restrictedAnnotation )")
       public Object processRequest(final ProceedingJoinPoint pjp, Restricted restrictedAnnotation) throws Throwable {
                  String[] roles = restrictedAnnotation.allowedRoles();
                  System.out.println("Allowed:" +  roles);
       }

это связывает аннотацию с параметром в сигнатуре метода restrictedAnnotation. Часть, в которой я не уверен, - это то, как она получает тип аннотации, похоже, основан на параметре. И как только у вас есть аннотация, вы можете получить значения.


Почему бы вам просто не использовать Весна Безопасности ? Это краткое для реализации и использования, я действительно не вижу смысла тратить время на изобретение колеса.


Whith Spring AOP, если у вас есть такая ситуация, как MyManagerImpl implements MyManager pointcut применяется к interface метод so MethodSignature описывает метод, определенный на MyManager У этого нет аннотации. единственный способ исправить это-проверить класс jp.getTarget() object и получить соответствующий метод.