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地址

 

 

 

  

 

  

posted @ 2017-10-16 15:43  周兴兴  阅读(1148)  评论(0)    收藏  举报