美文网首页首页投稿(暂停使用,暂停投稿)
代理模式(三) ---- 实现自定义代理逻辑的动态代理

代理模式(三) ---- 实现自定义代理逻辑的动态代理

作者: 偷星辰夜 | 来源:发表于2017-09-18 16:41 被阅读0次

上一篇我们实现了对所选择的接口的所有方法实现代理,但是代理逻辑却已经被写死了,自然不是很合适,这一篇我们便来解决这个问题,实现自定义代理逻辑的动态代理,实现之后我们的动态代理就已经很接近 JDK 自带的代理了。


  1. 要实现自定义代理逻辑,相信大家首先能想到的应该是定义一个接口 InvocationHandler ,我们所自定义的代理逻辑应该是实现了这个接口的逻辑类。
    InvocationHandler 代码:
    package dynamicProxy;
    
    import java.lang.reflect.Method;
    
    public interface InvocationHandler {
        void invoke(Object o ,Method method) ;
    }
    
  2. 定义一种代理逻辑,把目标对象跟方法传进来。这里还是采用之前的代理逻辑即时间代理。
    TimeHandler 代码:
    package dynamicProxy;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class TimeHandler implements InvocationHandler {
        public TimeHandler(Object target) {
            this.target = target;
        }
    
        private Object target ;
    
        @Override
        public void invoke(Object o, Method method) {
    
            long startTime = System.currentTimeMillis() ;
    
            try {
                method.invoke(target, new Object[]{}) ;
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
    
            long endTime = System.currentTimeMillis() ;
            System.out.println("time : " + (endTime - startTime)) ;
    
        }
    }
    
    
    这里的 target 为被代理对象,method.invoke(target, new Object[]{}) ; 中的 Object 数组是执行该方法的参数,这里为了简便操作先定义一个空数组。
  3. 接下来我们理所应当想到的就是修改生成代理类的工具,把代理逻辑也传进去。这里需要修改的地方有几处:
    • 修改生成代理类的类,添加 newInstance 方法的参数 InvocationHandler:
    public static Object newInstance(Class inface,InvocationHandler h)
    
    • 修改代理类的生成代码 str,构造方法不再是所给定的代理类,而是 InvocationHandler
    "public class TankTimeProxy implements "+ inface.getName() + "{\n" +
    "    public TankTimeProxy(InvocationHandler h) {\n" +
    "        this.handler = h;\n" +
    "    }\n" +
    "\n" +
    "    private InvocationHandler handler ;\n" +
    "\n" +
    
    • 方法字符串中,原本是执行方法的 invoke 方法(md.invoke(this, new Object[]{}) ;),现在改为执行 handler 的 invoke 方法
    "           handler.invoke(this, md) ; \n" +
    
    • 修改构造器参数:
    Constructor constructor = c.getConstructor(InvocationHandler.class) ;
    Object m = constructor.newInstance(handler);
    

实际上到了这里,我们要实现的动态代理就已经完成了,可以完成对任意接口的所有方法实现我们自定义的代理逻辑。

这里再给出 Client 代码 :

 Tank tank = new Tank() ;
Moveable tankTimeProxy = (Moveable)Proxy.newInstance(Moveable.class, new TimeHandler(tank)) ;
tankTimeProxy.move();

代码结果:

结果

最后有几点需要说明:

  1. 为什么代理类的构造方法要改为 InvocationHandler?
    我们已经知道,要实现代理肯定要有被代理对象,而我们在定义代理逻辑类的时候,已经把被代理对象作为构造方法的参数传进来了,所以代理类的构造方法定义为 InvocationHandler ,既包括了代理逻辑,也包括了被代理对象。
  2. 代理字符串中的 handler.invoke(this, md) 其中的 this 怎么理解?
    this 关键字相信大家都有所了解,就是当前对象。那么在代理类字符串中,this 自然代表了代理对象。而我们代理逻辑中,这个对象暂时没有用到,但不代表以后我们不会用到。在 JDK 中,这个代理类的名字叫 $Proxy1 有兴趣的可以去看看。

相关文章

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • Java动态代理解析

    动态代理原理解析 一. 代理模式例子: 目标类及代理类统一接口 目标实现类 自定义的代理模式处理程序 4.代理模式...

  • 代理模式vs装饰模式 and 静态代理vs动态代理

    目录:1.代理模式定义&实现2.装饰模式定义&实现3.静态代理4.动态代理:JDK动态代理、Cglib动态代理5....

  • 设计模式之代理

    设计模式之代理模式 一、定义 在Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及CGLIB动态...

  • 带你初识Java的代理模式

    Spring AOP是基于动态代理设计模式实现的,相对的就有静态代理 动态代理和静态代理 静态代理 对于静态代理,...

  • 代理模式(三) ---- 实现自定义代理逻辑的动态代理

    上一篇我们实现了对所选择的接口的所有方法实现代理,但是代理逻辑却已经被写死了,自然不是很合适,这一篇我们便来解决这...

  • 代理模式

    代理模式主要分为:静态代理,动态代理(JDK代理,接口代理)和Cglib代理(在内存中动态创建对象,不需要实现接口...

  • 代理模式

    代理模式分静态代理与动态代理,而动态代理又在Spring中与两个实现:1.基于JDK的动态代理(通过接口实现)2....

  • 【重温设计模式】代理模式

    前言 代理模式最典型的应用就是AOP,本文结合主要讲解了代理模式的几种实现方式:静态代理和动态代理,这里动态代理又...

  • Spring之代理模式

    九、代理模式 目录:静态代理、动态代理AOP的底层机制就是动态代理。代理模式分为静态代理和动态代理。接触aop之前...

网友评论

    本文标题:代理模式(三) ---- 实现自定义代理逻辑的动态代理

    本文链接:https://www.haomeiwen.com/subject/yjubsxtx.html