在我上一篇文章已经讨论过了,关于利用JDK 中的 Proxy 和 CGlib 创建虚拟子类的方式进行动态代理,Spring ProxyFactory 整合了两者还做了一堆Advice接口方便我们去做增强。
有以下增强接口
MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice 后面还有一会再说
/** * Created by yanzhichao on 26/04/2017. */ public class SpringLogAdvice implements MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice { Hashtable<Object,MethodMonitor> hashtable = new Hashtable<Object, MethodMonitor>(); //MethodBeforeAdvice public void before(Method method, Object[] objects, Object o) throws Throwable { MethodMonitor monitor = new MethodMonitor(true); hashtable.put(o,monitor); monitor.begin(o,method,objects); } //AfterReturningAdvice 的方法 public void afterReturning(Object returningObj, Method method, Object[] objects, Object target) throws Throwable { MethodMonitor monitor = this.hashtable.get(target); monitor.end(returningObj); this.hashtable.remove(target); } //这个方法不再ThrowsAdvice声明,spring是通过反射进行识别的,所以在文档中会有方法签名规范 void afterThrowing(Method method,Object[] args,Object target,RuntimeException e){ MethodMonitor monitor = this.hashtable.get(target); monitor.exception(e); this.hashtable.remove(target); } }
如果不太懂的话看之前的文章《动态代理之详细DEBUG日志模式》
需要注意的是,我虽然这样写但是在Spring的proxyfactory中是不允许我们实现多个advice到一个类中的,我这样写是让大家看得比较清楚不用分开几个文件,感觉这样比较傻。然后最好说说ThrowsAdvice 这个比较坑爹因为在接口里面没有写任何方法声明,所以我们需要记住spring反射读取的方法签名规范
afterThrowing(SQLException e);
afterThrowing(RuntimeException e);