getAnnotation爲null的坑
在寫一個基於SpringAOP的權限控制的。
自己定義了一個註解,然後邏輯代碼需要通過獲取自定義註解的一個屬性來進行權限控制。
下面簡單上一下關鍵代碼:
自定義註解:
@Documented //有關java doc的註解 @Retention(RetentionPolicy.RUNTIME) //保留時間,這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用. @Target(ElementType.METHOD) //針對方法 public @interface AuthorizationNeed { //自定義註解的屬性,default是設置默認值 //String operation() default "addAndUpdate"; String operation(); //這個屬性用來知道這是什麼操作,不同操作的寫法不一樣 }
切點:
/** * 定義個個切入點 * 所有有這個註解的方法 */ @Pointcut("@annotation(com.inforPoint.util.AuthorizationNeed)") private void needAuthorizationPoint() {}
然後在切面中有個@Around的環繞加強,需要在裏面獲取註解AuthorizationNeed的屬性operation的值。 在網上找了個方法,這是一開始的寫法:
//下面這句代碼是獲得那個自定義的註解的對象 AuthorizationNeed authorizationNeed = ( (MethodSignature)proceedingJoinPoint.getSignature() ).getMethod().getAnnotation(AuthorizationNeed.class); String operation = authorizationNeed.operation(); //用註解的時候有指明是什麼操作
但卻在運行的時候一直反應 這個authorizationNeed是null。
網上有說可能是註解的定義問題,要
@Retention(RetentionPolicy.RUNTIME)
但顯然不是這個錯。
後面百度了很久之後,原來是這個aop攔截的是ServiceImpl的一個方法,然後這個ServiceImpl又啓動了事務管理,而事務管理又是基於AOP的。
也就是說,這個權限的@Around的切面攔截的是個代理對象的方法,而代理對象的方法是不會把原來父類中的方法的註解加上去的,所以這裏這個註解的對象爲null。後面網上找到了一個可以解決問題的代碼:
/** * 這個方法幫忙拿出註解中的operation屬性 * 因爲有攔截serviceImpl的方法,而這些方法又加了事務管理,也就是這裏也有aop,這些已經是代理類,用之前的寫法獲得的是代理類的方法,而這些 * 方法是特麼不會把父類中的方法的註解加上去的!!! * @param proceedingJoinPoint */ private String getOperationOfTheAnnotation(ProceedingJoinPoint proceedingJoinPoint) throws Exception { Signature signature = proceedingJoinPoint.getSignature();//方法簽名 Method method = ( (MethodSignature)signature ).getMethod(); //這個方法纔是目標對象上有註解的方法 Method realMethod = proceedingJoinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), method.getParameterTypes()); AuthorizationNeed authorizationNeed = realMethod.getAnnotation(AuthorizationNeed.class); return authorizationNeed.operation(); }