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 и получить соответствующий метод.