• 动态代理解决方案


    调用不同对象的相同方法,前后都有相应操作,用动态代理的方案完成.
    在这里插入图片描述

    package com.hspedu.spring.proxy2;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * @author 45
     * @version 1.0
     * VehicleProxyProvider 该类可以返回一个代理对象.
     */
    public class VehicleProxyProvider {
    
        //定义一个属性
        //target_vehicle 表示真正要执行的对象
        //该对象的类实现了Vehicle接口
        private Vehicle target_vehicle;
    
        //构造器,要求传进一个实现了该接口的对象
        public VehicleProxyProvider(Vehicle target_vehicle) {
            this.target_vehicle = target_vehicle;
        }
    
        //编写一个方法,可以返回一个代理对象, 该代理对象可以通过反射机制调用到被代理对象的方法
        //老师解读
        //1. 这个方法非常重要, 理解有一定难度
        public Vehicle getProxy() {
    
            //得到类加载器
            ClassLoader classLoader =
                    target_vehicle.getClass().getClassLoader();
    
            //得到要代理的对象/被执行对象 的接口信息,底层是通过接口来完成调用
            Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();
    
    
            //创建InvocationHandler调用处理器 对象
            //接口不能被实例化,但就要的到其对象,所以使用匿名对象
            //因为 InvocationHandler 是接口,所以我们可以通过匿名对象的方式来创建该对象
            /**
             * 因为是接口里边的,所以此方法是抽象方法,并没有方法体,invoke意为调用
             * public interface InvocationHandler {
             *  public Object invoke(Object proxy, Method method, Object[] args)
             *         throws Throwable;
             * }
             * invoke 方法是将来执行我们的target_vehicle的方法时,会调用到
             *
             */
    
            InvocationHandler invocationHandler = new InvocationHandler() {
                /**
                 * invoke 方法是将来执行我们的target_vehicle的方法时,会调用到
                 * @param o 表示代理对象
                 * @param method 就是通过代理对象调用方法时,的哪个方法 代理对象Ship/Car.run()
                 * @param args : 表示调用 代理对象.run(xx) 传入的参数
                 * @return 表示 代理对象.run(xx) 执行后的结果.
                 * @throws Throwable
                 */
                @Override
                public Object invoke(Object o, Method method, Object[] args)
                        throws Throwable {
    
                    System.out.println("交通工具开始运行了....");
                    //这里是我们的反射基础 => OOP
                    //method 是?: public abstract void com.hspedu.spring.proxy2.Vehicle.run()
                    //target_vehicle 是? Ship对象
                    //args 是null
                    //这里通过反射+动态绑定机制,就会执行到被代理对象的方法
                    //执行完毕就返回
                    Object result = method.invoke(target_vehicle, args);
                    System.out.println("交通工具停止运行了....");
                    return result;
                }
            };
    
            /*
    
              public static Object newProxyInstance(ClassLoader loader,
                                              Class[] interfaces,
                                              InvocationHandler h)
    
              老师解读
              1. Proxy.newProxyInstance() 可以返回一个代理对象proxy
              2. ClassLoader loader: 类的加载器.
              3. Class[] interfaces 就是将来要代理的对象的接口信息
              4. InvocationHandler h 调用处理器/对象 有一个非常重要的方法invoke
             */
            Vehicle proxy =
                    (Vehicle)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    
            return proxy;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    package com.hspedu.spring.proxy2;
    
    import org.junit.jupiter.api.Test;
    
    /**
     * @author 45
     * @version 1.0
     */
    public class TestVehicle {
    
        @Test
        public void run() {
            //OOP基础=>java基础
            Vehicle vehicle = new Ship();
            //动态绑定
            vehicle.run();
        }
    
        @Test
        public void proxyRun() {
            //创建Ship对象
            Vehicle vehicle = new Car();
    
            //创建VehicleProxyProvider对象, 并且我们传入的要代理的对象
            VehicleProxyProvider vehicleProxyProvider =
                    new VehicleProxyProvider(vehicle);
    
    
            //获取代理对象, 该对象可以代理执行方法
            //老师解读
            //1. porxy 编译类型 Vehicle
            //2. 运行类型 是代理类型 class com.sun.proxy.$Proxy9
    
            Vehicle proxy = vehicleProxyProvider.getProxy();
    
            System.out.println("proxy的编译类型是 Vehicle");
            System.out.println("proxy的运行类型是 " + proxy.getClass());
            //下面老韩就要给大家解读/debug怎么 执行到 代理对象的 public Object invoke(Object o, Method method, Object[] args)
            //梳理完毕. proxy的编译类型是 Vehicle, 运行类型是 class com.sun.proxy.$Proxy9
            //所以当执行run方法时,会执行到 代理对象的invoke
            //如何体现动态 [1. 被代理的对象 2. 方法]
            proxy.run();
            String result = proxy.fly(10000);
            System.out.println("result=" + result);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    package com.hspedu.spring.proxy2;
    
    /**
     * @author 45
     * @version 1.0
     * 接口,该接口有run方法
     */
    public interface Vehicle {
        public void run();
        public String fly(int height);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    package com.hspedu.spring.proxy2;
    
    /**
     * @author 45
     * @version 1.0
     */
    public class Ship implements Vehicle{
        @Override
        public void run() {
            //System.out.println("交通工具开始运行了....");
            System.out.println("大轮船在水上 running....");
            //System.out.println("交通工具停止运行了....");
        }
    
        @Override
        public String fly(int height) {
            System.out.println("轮船可以飞翔 高度=" + height);
            return "轮船可以飞翔 高度=" + height;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    package com.hspedu.spring.proxy2;
    
    /**
     * @author 45
     * @version 1.0
     */
    public class Car implements Vehicle{
        @Override
        public void run() {
            //System.out.println("交通工具开始运行了....");
            System.out.println("小汽车在路上 running....");
            //System.out.println("交通工具停止运行了....");
        }
    
        @Override
        public String fly(int height) {
            System.out.println("小汽车可以飞翔 高度=" + height);
            return "小汽车可以飞翔 高度=" + height;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    Docker基础——4、Docker镜像 5、本地镜像发布到阿里云 6、本地镜像发布到私有库 7、 Docker容器数据卷 8、Docker常规安装简介
    Windows io完成端口
    THREE--demo8(文字)
    Hadoop 集群一直处于安全模式,强制退出后出现数据丢失警告。解决方法
    Golang开源流媒体服务器(RTMP/RTSP/HLS/FLV等协议)
    k8s教程:使用cert-manager证书管理工具在集群中提供https证书并自动续期
    可视化上证50结构图
    当年的java考试:Java景区预约登记管理系统(maven整合servlet)
    一些并查集的题~~判树,连通,带权
    【计算思维题】少儿编程 蓝桥杯青少组计算思维 数学逻辑思维真题详细解析第8套
  • 原文地址:https://blog.csdn.net/weixin_45036508/article/details/133025628