Spring AOP:如何获得建议方法的注释

时间:2010-04-01 09:05:30

标签: java security spring 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 个答案:

答案 0 :(得分:29)

对于仍然遇到 >将注释保留更改为运行时之后的问题,您可能遇到了同样的问题: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());    
}

如果您愿意,您也可以选择在此处理界面注释。

此处提供更多评论: getting template method instance from ProceedingJoinPoint

奥列格

答案 1 :(得分:13)

我认为@Restricted是你的注释。如果是这种情况,请确保您拥有:

@Retention(RetentionPolicy.RUNTIME)

在注释定义中。这意味着注释在运行时保留。

答案 2 :(得分:4)

即使在更改保留策略之后,如Bozho所提到的,此get to get调用也会返回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中的参数。我不确定的部分是它如何获得注释类型,它似乎是基于参数。一旦你有了注释,你就可以得到这些值。

答案 3 :(得分:2)

为什么不使用Spring Security?这是一个实施和使用的简短,我没有真正看到浪费时间重新发明轮子的重点。

答案 4 :(得分:2)

如果您遇到类似MyManagerImpl implements MyManager的情况,如果您的interface方法应用了切入点,那么MethodSignature MyManager描述了jp.getTarget()上定义的方法任何注释。我发现解决这个问题的唯一方法是检查{{1}}对象的类并检索相应的方法。