登录/注册
JAVA知识库
用 java.lang.reflect.Proxy 制作类似AOP 的方法调用 Log 层
转自:互联网
用Java.lang.reflect.Proxy制作类似AOP的方法调用Log层
个人认为,java.lang.reflect.Proxy简直是懒人必备的工具。
如,我负责编写一个分布式系统的一个服务,别的应用要调用我的服务的RMI接口方法。而多人开发有着一个必然的缺点:每人负责的模块均对外提供接口,但事情往往会因为接口的定义者、实现者、使用者间对接口理解的偏差,而在软件的开发中引出不少麻烦。于是,接口调用日志就有作用了。特别是RMI Interface的日志。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.text.MessageFormat; import java.util.Arrays; import org.apache.log4j.Level; import org.apache.log4j.Logger; /** *Afactoryofmethodinvokeloginterceptor. *logtheinvokeparamandresult. *@param<TargetInterface> */ publicclass InvokeLogProxyFactory < TargetInterface > { publicclass MyInvocationHandler implements InvocationHandler { private Level logLevel; private TargetInterface impl; public MyInvocationHandler(Level logLevel, TargetInterface impl) { this.logLevel = logLevel; this.impl = impl; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final Logger log = Logger.getLogger(impl.getClass()); String msg = MessageFormat.format("Calling method {0}({1})", method.getName(), Arrays.toString(args)); log.log(logLevel, msg); Object returnedResult = null; try { returnedResult = method.invoke(impl, args); } catch(InvocationTargetException e) { String msg1 = MessageFormat.format("Call method[{0}]: catch exceptions:", method.getName()); log.log(logLevel, msg1, e.getCause()); throw e.getCause(); } catch(Throwable e) { log.error("Runtime exception:", e); throw e; } log.log(logLevel, "returned val=" + returnedResult); return returnedResult; } } @SuppressWarnings("unchecked") public TargetInterface create(TargetInterface impl, Level logLevel) { MyInvocationHandler handler = new MyInvocationHandler(logLevel, impl); Object result = Proxy.newProxyInstance(impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), handler); return (TargetInterface) result; } }