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

我假设@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获取模板方法实例

奥列格

即使在改变保留策略之后,像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中的参数。 我不确定的部分是它如何获得注释类型,它似乎是基于参数。 一旦你有了注释,你就可以得到这些值。

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

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