如何使用log4j自动记录类中调用的每个方法

我有一个带数据库调用的类,我通常希望使用log4j记录此类中带有(带参数)的每个方法:

logger.debug("foo(id="+id+") initiated"); 

是否可以自动执行此操作? 也许在每个方法的开头使用某种注释而不是编写每个logger.debug?

今天我每次更改参数或方法名称时都必须更新我的logging.debug。

从jcabi-aspects尝试@Loggable注释和AspectJ 方面 (我是开发人员):

 @Loggable(Loggable.INFO) public String load(URL url) { return url.openConnection().getContent(); } 

所有方法调用都通过SLF4J记录。

这篇博客文章逐步解释: 使用AOP和Annotations进行Java方法记录

一种可能的解决方案是使用aspectj。 想法是将方面附加到您希望记录的每个方法,并且执行日志记录是方面而不是方法。 aspectj日志记录的一个示例就在stackoverflow中 。

如果您具有声明要将调用记录到的方法的接口,则可以使用标准Proxy API来实现所需。

Proxy API允许您将实际实现包装在一个新的代理类中,该类将记录调用,并将调用转发给实现。 您只需实现一个执行日志记录和转发的InvocationHandler

例如,

 interface Calculator { int add(int a, int b); } class CalculatorImpl implements Calculator { @Override public int add(int a, int b) { return a+b; } } class LoggingInvocationHandler implements InvocationHandler { private final Object delegate; public LoggingInvocationHandler(final Object delegate) { this.delegate = delegate; } @Override invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("method: " + method + ", args: " + args); return method.invoke(delegate, args); } } class X { public static void main(String... args) { final Calculator calc = new CalculatorImpl(); final Calculator loggingCalc = (Calculator) Proxy.newProxyInstance(X.class.getClassLoader(), new Class[] {Calculator.class}, new LoggingInvocationHandler (calc)); loggingCalc.add(2, 3); // shall print to the screen } } 

您还可以通过更改InvocationHandler的代码轻松记录方法抛出的返回值和exception。 此外,您可以使用您喜欢的任何日志记录框架而不是示例中的System.out.println

要记录返回值和exception,您可以执行以下操作:

  @Override invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("method: " + method + ", args: " + args); try { final Object ret = method.invoke(delegate, args); System.out.println("return: " + ret); return ret; } catch (Throwable t) { System.out.println("thrown: " + t); throw t; } }