我目前正在使用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
有什么方法不被认为是不好的做法吗?
答案 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
这就是你想要的吗?