• JDK 动态代理


    一、前言:

      设计模式,是一个好套路。Java 中有23种,都是靠前人一步一步总结出来的好东西。本项目的源码 GitHub 

    二、代理模式

      我在这里给大家简单的讲一下,用我在参加软件设计师资格证培训 课程中所学的例子。就是 司机开车出现交通事故,然后司机是不可能直接去和伤者(擦破了点皮) 进行直接对接的,因为怕被打。所有他会去找一个律师,让律师代表他去处理相关的事故问题。那么律师的职能就相当于代理。在代码中怎么体现?下面我们来看具体例子。

      1.定义接口

        在交通法律当中,处理交通事故的流程,那么就是一个接口。不管是司机、律师还是的赔偿都要按照法律程序来。那么我们就挑重点,选取 谈判赔偿 定义接口。

        

    package com.proxy.iservice;
    
    /**
     * 法律法规
     * @author TongZhou
     *
     */
    public interface ILayRules {
        
        /**
         * 谈判
         */
        public void negotiation();
        
        /**
         * 赔偿
         */
        public void satisfy();
    }

      2、实现接口的 司机 和 律师

        不管是司机自己还是律师代理,都要走法律程序。

      司机的实现类:

    package com.proxy.service;
    
    import com.proxy.iservice.ILayRules;
    
    /**
     * 司机
     * @author TongZhou
     *
     */
    public class Driver implements ILayRules{
    
        /**
         * 实现法律法规的谈判
         */
        @Override
        public void negotiation() {
            System.out.println(" 我愿意支付1000元的费用,为其治疗。 ");
            
        }
    
        /**
         * 司机实现了法理的付款条例
         */
        @Override
        public void satisfy() {
            System.out.println(" 司机支付了1000元!");
        }
    
    }

        都知道律师帮司机处理,当然是司机出钱去请律师,所以律师拥有司机作为成员就可以了。

        律师的实现类:

    package com.proxy.service;
    
    import com.proxy.iservice.ILayRules;
    
    /**
     * 律师也实现了法律规定
     * @author TongZhou
     *
     */
    public class Lawyer implements ILayRules{
    
        // 司机作为律师一个属性
        private Driver driver;
        
        public Lawyer(Driver driver) {
            this.driver=driver;
        }
        
        @Override
        public void negotiation() {
            
            System.out.println(" 我的客户的话: ");
            
            driver.negotiation();
            
        }
    
        @Override
        public void satisfy() {
            
            System.out.println(" 我客户支付了: ");
            driver.satisfy();
            
        }
    
    }

        调用方法查看效果。

    package com.proxy.face;
    
    import com.proxy.service.Driver;
    import com.proxy.service.Lawyer;
    
    public class Main {
    
        public static void main(String[] args) {
            
            //司机对象
            Driver driver=new Driver();
            
             //律师对象
            Lawyer lawyer=new Lawyer(driver);
            
            // 律师谈判
            lawyer.negotiation();
            
            //律师支付
            lawyer.satisfy();
    
        }
    
    }

      效果如下:

      

      那么这个是一个简单代理模式的案例!

    三、JDK 动态代理

      JDK 的动态代理,也是基于上述的代理模式。如果我们不知道 司机类会做出什么反应,那么我们就通过接口去拿到他的实现方法,不用在去写律师的类了。实现代码如下:

      

    package com.proxy.service;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import com.proxy.iservice.ILayRules;
    
    /**
     * 这是 JDK 的动态代理
     * 
     * @author TongZhou
     *
     */
    public class JDKProxy implements InvocationHandler {
    
        // 这是被代理的类
        private Driver driver;
    
        /**
         * 构造方法
         * 
         * @param driver
         */
        public JDKProxy(Driver driver) {
            this.driver = driver;
        }
    
        /**
         * 通过接口 拿到被代理类 的具体实现
         * 
         * @return 返回一个呗代理的新对象
         */
        public ILayRules createProxy() {
            /**
             * 获取代理对象
             * 
             * 这是通过对象的加载 应该了反射机制
             * 
             * driver.getClass().getClassLoader()  这是找到需要代理的类
             * 
             * driver.getClass().getInterfaces() 这是找到需要代理类继承的接口
             * 
             *  this 代表的当前的类 也就是 JDKProxy对象
             * 
             */
            ILayRules proxy = (ILayRules) Proxy.newProxyInstance(driver.getClass().getClassLoader(),
                    driver.getClass().getInterfaces(), this);
            
            // 这是通过类的加载 应用到了反射机制
            //ILayRules proxy=(ILayRules) Proxy.newProxyInstance(Driver.class.getClassLoader(), Driver.class.getInterfaces(), this);
            
            return proxy;
        }
    
        /**
         * 给被代理类增加代码
         * 
         * invoke方法中填写增强代码 调用代理对象的任何方法都会首先调用invoke方法
         * 
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if ("negotiation".equals(method.getName())) {
    
                System.out.println("司机的谈判内容是:");
    
                //传入需要加强的对象和参数
                Object result = method.invoke(driver, args);
    
                return result;
            }
            
            return method.invoke(driver, args);
        }
    
    }

      主函数的的测试代码:

    package com.proxy.face;
    
    import com.proxy.iservice.ILayRules;
    import com.proxy.service.Driver;
    import com.proxy.service.JDKProxy;
    import com.proxy.service.Lawyer;
    
    public class Main {
    
        public static void main(String[] args) {
            
            //司机对象
            Driver driver=new Driver();
            
    //         //律师对象
    //        Lawyer lawyer=new Lawyer(driver);
    //        
    //        // 律师谈判
    //        lawyer.negotiation();
    //        
    //        //律师支付
    //        lawyer.satisfy();
            
            //创建代理服务
            JDKProxy jdkProxy=new JDKProxy(driver);
            
            ILayRules iLayRules=jdkProxy.createProxy();
            
            iLayRules.negotiation();
            
            iLayRules.satisfy();
    
        }
    
    }

        测试结果:

        

      总结,这就是 JDK 的代理模式。感觉前人的设计 ,真的好牛 X 。 谢谢开发 JDK 的团队!

      本项目的源码 GitHub地址

      

      

  • 相关阅读:
    编程语言
    信安导论2020-2021上第九周总结(20201222)
    链节
    如何学好编程
    第八周学习总结(20201222)信安导论2020-2021上
    实现进制转化伪代码
    fibnacci数列递归实现
    求最大公约数伪代码
    20201332 熟悉编程语言
    如何学好编程(20201332)
  • 原文地址:https://www.cnblogs.com/gzbit-zxx/p/7675765.html
Copyright © 2020-2023  润新知