调用方法-记录为方法声明类

时间:2018-11-12 10:43:49

标签: java logging aop

我目前正在使用JBoss拦截器和Proxy类在运行时包装方法调用并记录一些统计信息。

这么说,拥有这段代码:

public class ProxyLoggingInterceptor <T> implements InvocationHandler {

private Logger logger = LoggerFactory.getLogger(ProxyLoggingInterceptor.class);


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        logger.info("%s.%s", t.getClass().getSimpleName(), method.getName());
    }
}

日志将产生如下内容:

12-11-2018 11:41.09,728 INFO (ProxyLoggingInterceptor) - [ANALYTICS]: MyClass.myMethod

但是,我想将记录声明类显示为记录器条目,即MyClass。 所需的结果将是:

12-11-2018 11:41.09,728 INFO (MyClass) - [ANALYTICS]: MyClass.myMethod

有什么方法不被认为是不好的做法吗?

1 个答案:

答案 0 :(得分:0)

实际上,我不是基于动态代理的AOP,我总是使用AspectJ来解决这类问题,因为原始类已被修改,因此很容易获得所需的信息。但是无论如何,由于它的 aop 标签找到了问题并且玩了一段时间,我想回答一下:

package de.scrum_master.app;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.function.Function;

public class ProxyLoggingInterceptor<T> implements InvocationHandler {
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.printf(
      "%s.%s%n",
      proxy.getClass().getGenericInterfaces()[0].getTypeName(),
      method.getName()
    );
    return null;
  }

  public static void main(String[] args) {
    ClassLoader classLoader = ProxyLoggingInterceptor.class.getClassLoader();

    Map mapProxy = (Map) Proxy.newProxyInstance(
      classLoader,
      new Class[] { Map.class },
      new ProxyLoggingInterceptor<Map>()
    );
    mapProxy.put("foo", 11);

    Function functionProxy = (Function) Proxy.newProxyInstance(
      classLoader,
      new Class[] { Function.class },
      new ProxyLoggingInterceptor<Function>()
    );
    functionProxy.apply("x");

    Runnable runnableProxy = (Runnable) Proxy.newProxyInstance(
      classLoader,
      new Class[] { Runnable.class },
      new ProxyLoggingInterceptor<Runnable>()
    );
    runnableProxy.run();
  }
}

控制台输出:

java.util.Map.put
java.util.function.Function.apply
java.lang.Runnable.run

这就是你想要的吗?