【问题标题】:Spring AOP: how to get the annotations of the adviced methodSpring AOP:如何获取建议方法的注释
【发布时间】:2010-04-01 09:05:30
【问题描述】:

我想用 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 代理的文章,但我不想使用这个代理。

【问题讨论】:

    标签: java security spring spring-aop


    【解决方案1】:

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

    如果你愿意,你也可以在这里处理接口注释。

    这里有更多可用的 cmets: getting template method instance from ProceedingJoinPoint

    奥列格

    【讨论】:

      【解决方案2】:

      我假设@Restricted 是您的注释。如果是这种情况,请确保您有:

      @Retention(RetentionPolicy.RUNTIME)
      

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

      【讨论】:

      • 非常感谢,这就是原因。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        你为什么不直接使用 Spring Security ?这是一个简单的实现和使用,我真的不明白浪费时间重新发明轮子的意义。

        【讨论】:

        • 谢谢,我会尽快看看
        【解决方案5】:

        如果您遇到类似MyManagerImpl implements MyManager 的情况,那么使用 Spring AOP 时,切入点将应用于 interface 方法,因此 MethodSignature 描述了在 MyManager 上定义的没有任何注释的方法。我发现解决此问题的唯一方法是检查 jp.getTarget() 对象的类并检索相应的方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-19
          • 1970-01-01
          • 2018-07-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多