Java基础---代理

目录

代理

1.代理是什么

 2.代理模式的好处

 3.java代理

基于jdk实现的静态代理 

静态代理的缺陷 

 基于jdk实现的动态代理


代理

1.代理是什么

 给目标对象提供一个代理对象,并且由代理对象控制对目标对象的引用

 代理本身是一种设计模式,用于为其他对象提供一种代理以控制对这个对象的访问。

 举一个简单例子

假如现在要你写一个系统向银行转账

首先你需要先去在一个类中完成转账的方法,要想调用当前转账方法就必须做

1.验证,如用户验证判断用户的身份是否正确以及转账金额验证,验证成功

2.转账

3.事后服务

根据以往的经验来说,不做任何的强调,正常写的话,就很有可能吧这三部分的东西混写成一个大的方法。

但是这样并不好,验证、转账、事后服务都是极其复杂的流程,如果全部写在一个方法中,就会使这个方法功能量太大。

 可能你就会想到,把一个方法转换为三个方法,按照顺序执行,每个方法都能完成单独的功能,不会造成冗余,这样是可行的,但是还有一个扩容的问题。

再举个例子

银行转账要求开放对支付宝,微信的转账

这就意味着,开放当前转账的接口,让支付宝和微信将其代理,把判断用户身份以及事后服务这两个部分,交给支付宝和微信自身处理,用户通过支付宝和微信的代理来实现转账这一核心方法,支付宝和微信代理着银行的转账,这个模式其实就是代理模式

 

 2.代理模式的好处

  • 防止用户直接访问核心方法带来一些不必要的危机
  • 能够对核心方法进行功能的增强!

 3.java代理

 代理模式分为:基于jdk实现的静态代理、基于jdk实现的动态代理、基于CGLB实现的动态代理

基于jdk实现的静态代理 

 图示法

 核心类也是目标类,核心对象也是目标对象。

 核心类,会生成核心对象,代理类去实现当前代理对象,再由代理对象去代理当前这个核心对象,这个过程是一个代理的过程,同时还有一个接口,核心类和代理类都会区实现当前接口,这就是静态代理的模式。

用代码去实现:

 ZhuanZhang接口,定义出核心方法

package 代理;

public interface ZhuanZhang {
    //定义核心方法
    public void zhuanzhang(String A,String B,Double money);
}

 YinHang核心类,实现ZhuanZhang接口,实现zhuanzhang方法

package 代理;

public class YinHang implements ZhuanZhang{
    @Override
    public void zhuanzhang(String A, String B, Double money) {
        System.out.println(A+"给"+B+"转了"+money+"元");
    }

}

 ZhiFuBao代理类,实现ZhuanZhang接口,实现zhuanzhang方法,并添加验证和事后服务功能

package 代理;
/*
 * 接口起到的作用就是通知代理类,所代理的核心是什么
 * */
public class ZhiFuBao implements ZhuanZhang{
    //定义好被代理类------》核心类
    private YinHang yinHang = new YinHang();

    private void yanzheng(String A,String B,Double money){
        System.out.println("对A进行了身份验证");
        System.out.println("对B进行了身份验证");
        System.out.println("对转账金额进行了验证");
    }
    @Override
    public void zhuanzhang(String A, String B, Double money) {//核心方法的实现
        yanzheng(A,B,money);
        yinHang.zhuanzhang(A,B,money);
        fuwu();
    }

    private void fuwu(){
        System.out.println("转账完成后进行服务");
    }
}

 Test类,用来测试

package 代理;

public class Test {
    public static void main(String[] args) {
        ZhiFuBao zhiFuBao = new ZhiFuBao();
        zhiFuBao.zhuanzhang("张三","李四",100.0);
    }
}

输出结果为:

对A进行了身份验证
对B进行了身份验证
对转账金额进行了验证
张三给李四转了100.0元
转账完成后进行服务 

内存图为

用户调用代理对象,由代理对象再去调用核心对象。 

接口这里起到沟通的作用

静态代理的缺陷 

 随着代理类所代理的目标类增多,每增加一个目标类,就需要对代理类进行扩充。

每个代理对象代理的目标太多

 用一个代理类代理多个目标类是很难实现的

  •  如果接口中的方法很多,那么代理类中也需要实现相同数量的方法,这会导致代理类变得庞大且难以维护。
  • 如果被代理类有很多,那么就需要为每一个被代理类都编写一个代理类,这进一步增加了代码的冗余和复杂性。

 基于jdk实现的动态代理

 动态代理生成代理对象,分别只包含自己要代理的对象。

代码示例

Shoes接口

package 动态代理;

public interface Shoes {

    public void ByShoes(String size);

}

Clothes接口

package 动态代理;

public interface Clothes {

    public void ByClothes(String size);

}

 ClothesFactory类实现Clothes接口,实现ByClothes方法

package 动态代理;

public class ClothesFactory implements Clothes {
    @Override
    public void ByClothes(String size) {
        System.out.println("定制一件大小为"+size+"的衣服");
    }
}

ShoeFactory类实现Shoes接口,实现BByShoes方法

package 动态代理;

public class ShoeFactory implements Shoes{
    @Override
    public void ByShoes(String size) {
        System.out.println("定制一款大小为"+size+"的鞋子");
    }
}

DTXSD 实现InvocationHandler接口,实现getProxyInstance(),invoke(),fuwu()方法

package 动态代理;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DTXSD implements InvocationHandler{
    private Object object;  
    public DTXSD(Object o) {//传入目标类的目标对象(代理类的代理对象) 动态代理类一对一的形成
        object = o;
    }

    /**
     * 动态代理实现相关接口
     * 调用该方法你就知道了目标类当中的核心方法是什么
     * @return
     */
    public Object getProxyInstance(){  //object.getClass() 获取目标类的类对象 getInterfaces()获取目标类的接口
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),this);
    }
    //固定写法
    //三个参数的讲解
    //1.Object:jdk创建的代理类,无需赋值
    //2.Method:目标类当中的方法,jdk提供,无需赋值
    //3.Object[]:目标类当中的方法的参数,jdk提供,无需赋值
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(object,args);
        fuwu();
        return null;
    }
    private void fuwu(){
        System.out.println("销售店进行一系列的服务");
    }
}

 Test类

package 动态代理;

public class Test {
    public static void main(String[] args) {

          ClothesFactory clothesFactory = new ClothesFactory();//可以使用反射创建对象
          DTXSD dtxsd1 =  new DTXSD(clothesFactory);
          //已经知道了目标类当中的核心方法是什么
          Clothes clothes = (Clothes) dtxsd1.getProxyInstance();//用相关接口来进行接收
          clothes.ByClothes("XXL");//使用相关接口来调用当前方法

          ShoeFactory shoeFactory =new ShoeFactory();
          DTXSD dtxsd2 = new DTXSD(shoeFactory);
          Shoes shoes = (Shoes) dtxsd2.getProxyInstance();
          shoes.ByShoes("42");
    }
}

输出结果为: 

定制一件大小为XXL的衣服
销售店进行一系列的服务
定制一款大小为42的鞋子
销售店进行一系列的服务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值