在Java中运行时捕获方法的参数

问题描述:

我们的应用程序使用多个后端服务,并维护包含实际服务调用方法的包装。如果在调用服务时出现这些方法中的任何异常,我们会抛出一个封装原始异常的自定义异常,如下所示。在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

使用AspectJ,您可以use around advice执行建议,而不是连接点上的代码。然后,您可以通过调用proceed来从建议中执行实际的连接点。这将允许您捕获输入参数,记录它们,并继续调用实际方法。

在相同的建议中,您可以捕获从方法中抛出的任何日志,并在将它们传递回更高级别之前检查或记录它们。

AspectJ是正确的选择。您将能够通过将传递给您的advise方法的JoinPoint对象来获取参数。您也可以通过执行投掷后建议或周围建议来获得例外。

马特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; 
    } 
    } 
}