主页 > 游戏开发  > 

多层代理模式解析Invocation

多层代理模式解析Invocation
场景

试想一下,在另一种场景下看,需要使用JDK代理模式对最终目标对象实现增强。 例如,有一个目标对象A,框架需要提供一种能力,来实现对A的增强,所谓的增强,就是可以在执行A之前做一些事,执行A之后做一些事。这就是增强。 增强的实现: 1. 过滤器链的思想 2. SpringMVC拦截器思想,MVC的拦截器思想,总体来说不是一个链式执行的过程,虽然效果和调用栈一个样,但是在代码底层执行时不是嵌套增强,而是串行增强。 3. 代理增强。 场景; 有一个目标对象A,实现AI接口 插件提供一个接口Advice,实现了Advice接口的类可以动态对A对象实现嵌套式增强,多个增强可以指定顺序、需使用代理模式实现。

Advice1 Advice2 Target... 嵌套式调用,再每一个增强中调用下一个增强。 既然是这种设计,那么肯定有一个地方,将这个嵌套逻辑代码给组装起来,并且每一个增强器都可以直接或者间接调用到下一个增强器。 也就是框架需要具备这种能力。 设计思想:既然是基于接口调用实现增强,那么需要使用JDK动态代理对代理对象生成多种代理。每一层代理增强都是嵌套实现前后置增强。而且这个增强还得靠用户控制。 基于原始对象生成代理对象后,这个代理对象获取接口也是生成这个代理对象时的实现接口。 代码实现 public interface TargetInterface { public void doTarget(); } public class TargetObject implements TargetInterface { public void doTarget() { System.out.println("目标对象执行"); } } public interface Advice { /* 给每一个增强器设置下一个增强器调用栈 */ public Object doAdvice(TargetInvoke targetInvoke) throws Throwable; } @Data @AllArgsConstructor @NoArgsConstructor public class TargetInvoke { //下一个增强对象 private Object nextAdvice; //增强的方法 private Method method; //调用方法的参数 private Object[] args; /** * 下一个实现,分析 Proxy.invoke, A B C 很明显,A对象需要获取B对象的引用 而B对象需要获取C对象引用,本质上其实是获取下一个增强的处理。 */ public Object invoke() throws Exception { return method.invoke(nextAdvice,args); } } public class LogAdvice implements Advice { @Override public Object doAdvice(TargetInvoke targetInvoke) throws Throwable { System.out.println("log advice before"); Object res = targetInvoke.invoke(); System.out.println("log advice after"); return res; } } public class AuthAdvice implements Advice { @Override public Object doAdvice(TargetInvoke targetInvoke) throws Throwable { System.out.println("auth advice before"); Object res = targetInvoke.invoke(); System.out.println("auth advice after"); return res; } } public class ProxyUtil { public static TargetInterface getProxy(TargetInterface target, Advice advice) { return (TargetInterface) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy,method,args) -> { //执行第一个增强,同时需要给这个增强设置下一个增强。 TargetInvoke targetInvoke = new TargetInvoke(target,method,args); Object res = advice.doAdvice(targetInvoke); return res; } ); } } public class Test { public static void main(String[] args) { TargetInterface targetObject = new TargetObject(); List<Advice> adviceList = Arrays.asList( new AuthAdvice(), new LogAdvice() ); //循环增强,使用每一个增强器创建代理对象,实现层层包装。 for (Advice advice : adviceList) { //这里通过多层循环,使得代理层级层层封装 targetObject = ProxyUtil.getProxy(targetObject,advice); } targetObject.doTarget(); } }
标签:

多层代理模式解析Invocation由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“多层代理模式解析Invocation