OP 在评论中提到首选解决方案是使用纯 java 代理。当前代码是作为静态方法实现的——为了使 java 代理有任何用途,记录器类需要重新设计为接口。像这样的东西:
public interface SomeActionLogger
{
void logSomeAction();
void logSomeOtherAction();
// etc..
}
然后你创建你的具体实现
public class SystemOutActionLogger implements SomeActionLogger
{
public void logSomeAction () {
System.out.println (msg(SOME_ACTION));
}
}
然后,您可以让 Java 代理包装SomeActionLogger
接口
class DelayAfterInvocationHandler implements InvocationHandler
{
private Object delegate;
private int duration;
DelayAfterInvocationHandler(Object delegate, int duration)
{
this.delegate = delegate;
this.duration = duration;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Object returnValue = method.invoke(delegate, args);
Thread.sleep(duration);
// you may want to catch InterruptedEception
return returnValue;
}
}
要隐藏一些不那么漂亮的代理代码,您可以使用一种方法来包装您的记录器以创建延迟,例如
public ActionLogger addDelay(SomeActionLogger logger, int delay)
{
return (ActionLogger)Proxy.newProxyInstance(
impl.getClass().getClassLoader(),
new Class[] { SomeActionLogger.class },
new DelayAfterInvocationHandler(logger, delay));
}
所以你然后写
SomeActionLogger log = addDelay(new SystemOutActionLogger(), 2000);
请注意,它DelayInvocationHandler
与日志接口正交 - 它可用于向任何接口添加延迟。然后,您可以创建一个通用的包装方法,如下所示:
public <T> T addDelay(T delegate, int delay, Class<T> interfaceType)
{
return (T)Proxy.newProxyInstance(
delegate.getClass().getClassLoader(),
new Class[] { type },
new DelayAfterInvocationHandler(delegate, delay));
}