Java之代理模式

1.静态代理

目标:
    能够使用动态代理   生成一个代理对象
为什么需要代理:
    生活中有很多代理的例子,比如,你要出国旅游,你又很麻烦于办签证,预定机票和酒店,租车
    那么,我们可以选择旅行社帮我们去一条龙操作,这个时候旅行社就是我们的代理,而我们是被代理
代理模式:
    被代理者没有能力或者不愿意完成某件事情,就需要委托他人帮自己完成这件事,这个人就是代理者
    所以,代理模式中包含了三个角色:被代理者【自己】、代理者【委托人】、抽象角色【协议】

@案例:
      张三要找租车
      代理模式的定义:代理者 帮助 被代理者 去做 被代理者不愿意或者没有能力去完成的某件事情,所以代理者去做被代理者的事情
      张三 委托 租车公司 去帮 自己 车

定义一个Car类

public interface Car {
    /*
    * 协议,被代理者需要代理的方法,就定义在这个地方,然后让代理者和被代理者都去实现
    *
    * 被代理者实现:为了确保和代理者实现的方法一致
    * 代理者实现:为了增强被代理者的这些方法
    * */
    public abstract void car();
}

定义一个张三类

public class Zhangsan implements Car{


    @Override
    public void car() {
        System.out.println("张三在开车");
    }
}

定义一个租车公司类

public class Crc implements Car{

    //代理者的任务就是帮被代理者去做代理者不愿意去做的事情
    //代理者其实就是在帮被代理者增强被代理者想要做的事情
    //所以说到增强方法,其实就是使用【装饰者模式】

    //成员方法
    Zhangsan zhangsan;
    //构造方法
    public Crc(Zhangsan zhangsan) {
        this.zhangsan = zhangsan;
    }

    @Override
    public void car() {
        System.out.println("张三在租车公司租了一辆车");
        // 张三开始开车
        zhangsan.car();
        System.out.println("张三开完车把车还回去");
    }



}

测试类

public class Tests {

    public static void main(String[] args) {


        //  不请代理的话,张三直接去找车
        Zhangsan zhangsan = new Zhangsan();
        //zhangsan.car();


        // 找代理
        Car crc = new Crc(zhangsan);    //crc是代理对象  CRC是代理类  Car接口是协议   zhangsan是被代理对象  Zhangsan是被代理类
        crc.car();
        /*
         * 从以上代码中,我们可以看到,zhangsan的代理对象是 crc,代理对象是确定知道是谁的,所以这种一般本人称之为静态代理
         *
         * */

    }
}

从以上代码中,我们可以看到,zhangsan的代理对象是 crc,代理对象是确定知道是谁的,所以这种一般称之为静态代理

2.动态代理模式

动态代理:
    就是直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
动态代理的获取
    JDK提供的一个Proxy类,可以直接给实现接口的对象     直接生成一个代理对象
问题:
    张三不方便找车,或者没有渠道找车
    张三的car方法需要增强一下
静态代理:代理类是真实存在的,通过代理类产生代理对象
动态代理:代理类是不真实存在的,在程序运行过程中,直接产生代理对象
    概述:动态代理就是直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
提前:
    被代理类需要实现接口
动态代理实现获取代理对象
    JDK提供的一个Proxy类,这个类可以直接  给实现接口类的对象【被代理者】 直接生成代理对象【代理者】
        例如:使用Proxy直接给Zhangsan生成一个代理对象该对象所属的类不需要知道
    java.lang.reflect.Proxy类可以直接生成一个代理对象
        - public static Object newProxyInstance(ClassLoader loader,
                               Class<?>[] interfaces,
                               InvocationHandler h)
            生成一个代理对象
            参数1:ClassLoader loader,被代理类的加载器
            参数2:Class<?>[] interfaces,被代理类所有实现的接口的Class对象
            参数3:InvocationHandler h,执行处理类
                    前两个参数都是为了帮助在JVM内部生成被代理类的代理对象
                    第三个参数就是用来监听代理对象调用的方法,帮助我们代理对象调用方法的
                    java.lang.reflect.InvocationHandler,是一个接口

定义一个car类

public interface Car {
    /*
    * 协议,被代理者需要代理的方法,就定义在这个地方,然后让代理者和被代理者都去实现
    *
    * 被代理者实现:为了确保和代理者实现的方法一致
    * 代理者实现:为了增强被代理者的这些方法
    * */
    public abstract void car();
}

定义一个张三类

public class Zhangsan implements Car {


    @Override
    public void car() {
        System.out.println("张三在开车");
    }
}

定义一个测试类

public class Tests {

    public static void main(String[] args) {

        Zhangsan zhangsan = new Zhangsan();
        // 动态代理
        Car car = (Car) Proxy.newProxyInstance(Zhangsan.class.getClassLoader(), Zhangsan.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                /*
                 * invoke(),就是一个回调方法:当代理对象调用了方法,就会来执行该invoke方法,在该方法中就可以增强被代理类的方法
                 *
                 *      参数1:Object proxy,生成的代理对象,这里就是car这个代理对象(不用),这里一旦使用代理对象就会产生递归
                 *      参数2: Method method,当前代理对象执行的方法,这里的method指的就是car()方法对象
                 *      参数3:Object[] args, 当前代理对象执行的方法的返回值
                 * */
                //System.out.println("invoke");

                // 确保要代理的方法,因为zhangsan可能需要代理多个方法
                if (method.getName().equals("car")) {
                    System.out.println("张三在租车公司租了一辆车");
                    // 通过反射来调用被代理对象的方法,调用就是happy()方法,没有参数
                    method.invoke(zhangsan);
                    System.out.println("归还");
                }
                return null;
            }
        });
        // 代理对象car,执行car方法的时候,就会调用上面的增强的方法invoke()
        car.car();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值