• Java——静态代理、动态代理


     https://blog.csdn.net/giserstone/article/details/17199755

    代理的作用:业务类只需要关注业务逻辑本身,保证了业务类的重用性

    一 静态代理

    特点:

      程序运行前就已经存在代理类的字节码文件了,代理类和委托类的关系也在程序运行前就确定了 

    实现:

      代理类继承了被代理类的接口;代理类将被代理类以成员变量的方式引入,在构造函数中初始化被代理类;共同接口中,引用成员变量的方法并在该接口中增加新功能以实现代理类的功能。

    缺点:

      1)代理对象的一个接口只能服务于一种被代理对象,每有一种代理对象,就要多一个代理方法。

      2)代理类在程序一开始就要被加载,增加了内存负担

      3)如果接口类增加了一个方法,除了被代理对象要增加这个接口,代理对象也要增加这个接口,增加了程序维护的复杂度

      4)只能代理已知的对象

    二 动态代理

    特点:

      动态代理的字节码是在程序运行期间由JVM根据反射机制动态生成的,不存在代理类的字节码文件,代理类和委托类的关系是在程序运行时确定的

    实现:

      1)实现InvocationHandler接口创建自己的调用处理器
      2)给Proxy类提供ClassLoader和代理接口类型数组创建动态代理类
      3)以调用处理器类型为参数,利用反射机制得到动态代理类的构造函数
      4) 以调用处理器对象为参数,利用动态代理类的构造函数创建动态代理类对象

    demo:

    接口:

    package com.test.aoptest.proxyTest;
    
    public interface MyTask {
        void doing();
    
        void writing();
    }

    委托类:

    package com.test.aoptest.proxyTest;
    
    public class MyTaskImpl implements MyTask {
        @Override
        public void doing() {
            System.out.println("doing sth ...");
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void writing() {
            System.out.println("writing sth ...");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    调度器:

    package com.test.aoptest.proxyTest;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class MyTaskInvocationHandler implements InvocationHandler {
    
        private Object delegate;
    
        public MyTaskInvocationHandler(Object delegate) {
            this.delegate = delegate;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            long start = System.currentTimeMillis();
            Object result = method.invoke(delegate, args);
            long end = System.currentTimeMillis();
            System.out.println("执行任务耗时"+(end - start)+"毫秒");
            return result;
        }
    }

    主入口:

    package com.test.aoptest.proxyTest;
    
    import java.lang.reflect.Proxy;
    
    public class Client {
        public static void main(String[] args) {
    
            MyTaskImpl myTask = new MyTaskImpl();
            MyTask proxy = (MyTask) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
                    new Class[]{MyTask.class}, new MyTaskInvocationHandler(myTask));
            proxy.doing();
            proxy.writing();
    //        System.out.println(proxy.hashCode());
    //        System.out.println(myTask.hashCode());
    //        System.out.println(myTask.equals(proxy));
    //        System.out.println(myTask.toString());
    //        System.out.println(proxy.toString());
        }
    }

     System.identityHashCode(Object) 返回对象的内存地址,不管该对象的类是否重写了hashCode()方法。

  • 相关阅读:
    windows server 2012 流媒体服务器搭建(直播与点播)
    开源的电商 B2C、B2B2C 电商系统-关于shopnc版权问题处处是陷阱啊
    windows远程桌面无法粘贴复制的问题解决方法
    通过$.ajax设置预加载动画加强用户体验
    怎么样抢注新域名
    某些浏览器具有dns缓存功能,大家更改域名指向,建议清理下浏览器缓存
    jQuery的on绑定事件在mobile safari(iphone / ipad / ipod)上无法使用的解决方案
    sqlserver Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应
    解决jQuery ajax动态新增节点无法触发点击事件的问题
    php递归函数中使用return的注意事项
  • 原文地址:https://www.cnblogs.com/gaoquanquan/p/11269706.html
Copyright © 2020-2023  润新知