From 9569a3d37bb2b14b69bc5c99090dadeb8789a9a7 Mon Sep 17 00:00:00 2001 From: aoshiguchen <1052045476@qq.com> Date: Thu, 30 Jun 2022 16:42:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Eaop=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=9A=84=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Aop.MD | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 docs/Aop.MD diff --git a/docs/Aop.MD b/docs/Aop.MD new file mode 100644 index 00000000..c0b1af9a --- /dev/null +++ b/docs/Aop.MD @@ -0,0 +1,41 @@ +# 动态代理策略 +- `AUTO` 框架按照一定策略动态选择代理方式 +- `JDK_DYNAMIC_PROXY` JDK动态代理 +- `ASGC_PROXY` 子类继承代理(傲世孤尘代理) + +# 自动代理策略 +> 当被代理类是一个接口时,采用JDK动态代理,否则采用子类代理 + +# JDK动态代理 +> 目前仅支持代理接口,不支持为普通类生成代理。 +> 原因是:JDK动态代理生成的代理类,不能用被代理类的类型接收,而必须用被代理类的接口类型接收,这与目前的设计结构有冲突,后续需要思考优化解决 + +# 子类继承代理 +> 顾名思义,通过生成一个被代理类的子类来创建一个代理类实例,因此可以用被代理类类型接收代理实例。 +> 可代理接口、普通类。不能代理静态类、内部类、final修饰的类、final修饰的方法,暂不支持代理抽象类。 + +# 拦截器 +> 所有拦截器实例都是单例的,与bean容器打通(这块后期着重优化) + +- `全局拦截器` 全局维护,由所有代理类共享的拦截器,根据需要可以过滤。 +- `普通拦截器` 代理实例维护,不同的代理实例可共享,需要在被代理类或者方法上加`@Intercept`注解标注 +- `过滤器` 阉割版的拦截器,用于在目标方法执行前进行过滤操作 +- `结果处理器` 阉割版的拦截器,用于在目标方法执行完毕正常返回后,对返回数据进行处理 +- `异常处理器` 阉割版的拦截器,用于在目标方法执行抛异常后,对异常进行捕获处理 + +# 拦截器的继承 +> 不是父类子类的继承,类似于财产的继承。按照继承关系依次是:全局拦截器 -> 类拦截器 -> 方法拦截器 +- 所有的代理类都继承全局拦截器,前提是代理类没有排除全局拦截器 +- 所有的可代理方法都继承类上的拦截器(`@Intercept`在类上标注的拦截器),前提是方法上没有标注排除类上的拦截器。 +- 特别的,如果被代理类是一个接口。则这个接口会继承所有父接口的拦截器。 + +# 拦截器的执行顺序 +- 对于普通类来说,拦截器按照继承顺序执行,也就是会首先执行全局拦截器 +- 对于接口来说,先按照拦截器继承顺序,再按照接口继承层级向上传递。如:全局拦截器 -> 类拦截器 -> 方法拦截器 -> 父接口拦截器 -> 爷接口拦截器 -> ... + +# 拦截器的异常处理流程 +-> 异常处理与拦截器执行顺序相反,类似与冒泡的过程。 +- 末端拦截器处理,若未能捕获,则继续流转 +- 全局拦截器处理,若未能捕获、则继续流转 +- 若被代理方法声明了对外抛出,则抛给应用层,否则继续流转 +- 代理方法处理,直接打印堆栈信息