2011-04-19 25 views
34

問題很簡短:是否有一種方式來獲得從apsectj ProceedingJoinPoint的Method對象?從ProceedingJoinPoint獲取java.lang.reflect.Method?

目前我做

Class[] parameterTypes = new Class[joinPoint.getArgs().length]; 
Object[] args = joinPoint.getArgs(); 
for(int i=0; i<args.length; i++) { 
    if(args[i] != null) { 
     parameterTypes[i] = args[i].getClass(); 
    } 
    else { 
     parameterTypes[i] = null; 
    } 
} 

String methodName = joinPoint.getSignature().getName(); 
Method method = joinPoint.getSignature() 
    .getDeclaringType().getMethod(methodName, parameterTypes); 

,但我不認爲這是要走的路...

回答

68

你的方法是沒有錯的,但有一個更好的。你必須轉換爲MethodSignature

MethodSignature signature = (MethodSignature) joinPoint.getSignature(); 
Method method = signature.getMethod(); 
+0

當在彈簧引導應用使用上述轉換失敗。然後簽名是類型MethodSignatureImpl,它是一個私有的彈簧MethodInvocationProceedingJoinPoint的內部類。 – Heri 2015-06-11 18:03:11

+6

更新上述評論(這是錯誤的):在我的測試中,我輸入了錯誤的MethodSignature類導致一個ClassCastException。正確的類是org.aspectj.lang.reflect.MethodSignature。 – Heri 2015-06-11 21:55:18

36

你應該小心,因爲Method method = signature.getMethod()將返回接口的方法,你應該添加這是一定要得到實現類的方法:

if (method.getDeclaringClass().isInterface()) { 
     try { 
      method= jointPoint.getTarget().getClass().getDeclaredMethod(jointPoint.getSignature().getName(), 
        method.getParameterTypes()); 
     } catch (final SecurityException exception) { 
      //... 
     } catch (final NoSuchMethodException exception) { 
      //...     
     } 
    } 

(漁獲的代碼是自願空的,你最好添加代碼來管理除外)

有了這個,你就必須執行,如果你要訪問的方法和參數的註釋,如果這一個沒有在接口

+0

如果我能我會給予好評你兩次,一次爲偉大的答案,一次'jointpoint' – Taylor 2017-05-02 02:36:50