2011-03-23 20 views
1

我們的應用程序使用多個後端服務,並維護包含實際服務調用方法的包裝。如果在調用服務時出現這些方法中的任何異常,我們會拋出一個封裝原始異常的自定義異常,如下所示。在Java中運行時捕獲方法的參數

interface IServiceA { 
public void submit(String user, String attributes); 
} 

public class ServiceAWrapper implements IserviceA { 
private ActualService getActualService() { 
    ..... 
} 

public void submit(String user, String attributes) { 
    try { 
    Request request = new Request(); 
    request.setUser(user); 
    request.setAttributes(attributes); 
    getActualService().call(request); 
    } catch(ServiceException1 e) { 
    throw new MyException(e, reason1); 
    } catch(ServiceException2 e) { 
    throw new MyException(e, reason2); 
    } 
} 
} 

我想知道是否有任何框架,讓我

  1. 捕獲(可能數)通過了所有的 參數,以我的包裝在運行時 方法;如果調用方法 。
  2. 捕獲實際異常 對象(MyException實例在上面的 示例中),如果有的話拋出;這樣我 可以在運行時將傳遞的參數 附加到對象。

我目前正在探索AspectJ以查看它是否可以解決我的需求,但我不確定它是否可以用於捕獲在運行時傳遞給方法的參數,並捕獲異常對象(如果有)。

謝謝。

+0

你好,感謝您的答覆。我目前使用'JoinPoint'來捕獲參數。但是,我發現'JoinPoint'中的'getArgs()'方法只返回了參數的值而不是它們的名字。我怎樣才能檢索參數的名稱呢? – soontobeared 2011-04-19 02:03:20

回答

4

使用AspectJ,您可以use around advice執行建議,而不是連接點上的代碼。然後,您可以通過調用proceed來從建議中執行實際的連接點。這將允許您捕獲輸入參數,記錄它們,並繼續調用實際方法。

在相同的建議中,您可以捕獲從方法中拋出的任何日誌,並在將它們傳遞迴更高級別之前檢查或記錄它們。

0

AspectJ是正確的選擇。您將能夠通過將傳遞給您的advise方法的JoinPoint對象來獲取參數。您也可以通過執行投擲後建議或周圍建議來獲得例外。

3

馬特B的答案是正確的。具體來說,你可以這樣做:

 
aspect MonitorServiceCalls { 

    private final Logger LOG = LoggerFactory.getLog("ServiceCallLog"); 

    Object around() throws MyException: call(public * *(..) throws MyException) 
             && target(IServiceA+) { 
    MethodSignature msig = (MethodSignature)thisJoinPoint; 
    String fullMethName = msig.getMethod().toString(); 
    try { 
     Object result = proceed(); 
     LOG.info("Successful call to {} with arguments {}", 
       fullMethName, 
       thisJoinPoint.getArgs()); 
     return result; 
    } catch(MyException e) { 
     LOG.warn("MyException thrown from {}: {}", msig.getMethod(), e); 
     throw e; 
    } 
    } 
}