java代理

1、什么是代理

转账类里有一个转账方法

public class 转账{

public void 转账(String A,String B,Integer money){

System.out.println("A转给B“+money+"元");

}

}

市面上常用的转账方法是ZFB和VX,银联二维码等被ZFB、VX扫码后执行支付功能。这里的二维码实现了跨平台功能。

因为以ZFB为例,银联只需开发转账方法(如上),ZFB实现代理功能,通过支付宝平台 无需开发自己的支付软件 便可得到收益且规避了一定的风险。即给目标对象一个代理对象,由代理对象控制着对目标对象的引用。

2、为什么使用代理?

1、功能增强:通过代理业务对原有业务进行增强

2、用户只能通过代理对象间接的访问目标对象,防止用户直接访问目标对象给系统带来不必要的复杂性!

java代理_第1张图片

3、代理的两种方式:静态、动态代理

◼️静态代理及实现方式

/**
 * 衣服工厂  目标类
 */
public class ClothesFactory implements Clothes{  //实现相应接口
    //核心方法
    public void byClothes(String size){
        System.out.println("为您定制一件大小为"+size+"的衣服");
    }
}
/**
 * 鞋子工厂  目标类
 */
public class ShootFactory implements Shoot{
    //核心方法
    public void byShoot(String size){
        System.out.println("为您定制一双大小为"+size+"的鞋子");
    }
}
/**
 * 鞋子接口
 */
public interface Shoot {
    public void byShoot(String size);
}
/**
 * 衣服接口
 */
public interface Clothes {
    public void byClothes(String size);
}
/**
 * 静态代理类
 */
public class Agent implements Clothes,Shoot{
    //1、控制访问
    ClothesFactory clothesFactory=new ClothesFactory();
    ShootFactory shootFactory=new ShootFactory();
    //2、提供方法
    public void byClothes(String size){
        System.out.println("量身定制");
        clothesFactory.byClothes(size);
        System.out.println("打包快递");
        System.out.println("*********************");
    }
    public void byShoot(String size){
        System.out.println("量身定制");
        shootFactory.byShoot(size);
        System.out.println("打包快递");
        System.out.println("*********************");
    }
}
/**
 * 顾客
 */
public class Person {
    public static void main(String[] args) {
        Agent proxy=new Agent();  //proxy代理对象
        proxy.byClothes("xl");
        proxy.byShoot("42");
    }
}

java代理_第2张图片

java代理_第3张图片

图示解释什么是静态代理

java代理_第4张图片

java代理_第5张图片

随着目标类(被代理的类)的增多,代理类需要代理的目标类也会增多,一个代理类生成多个对象。每一个目标对象都是代理着多个目标对象

=====> 静态代理问题当我们的目标类增多的时候,代理类需要代理的目标类增多,可能会出现代理关系不便。当我们的目标类进行修改或增多的时候,会影响目类以及要改动代理类

java代理_第6张图片

静态代理的缺陷

(1)代理复杂,难于管理

代理类和目标类实现了相同的接口,每个代理都需要实现目标类的方法,这样就出现了大量的代码重复。如果接口增加一个方法,除了所有目标类需要实现这个方法外,所有代理类也需要实现此方法。——>增加了代码维护的复杂度。

(2)代理类依赖目标类+代理类过多

代理类只服务于一种类型的目标类,如果要服务多个类型。势必要为每一种目标类都进行代理,静态代理在程序规模稍大时就无法胜任了,代理类数量过多。

补充:静态代理只适合业务功能固定不变的情况。(业务接口方法不进行增加和减少,实现类就不需要改动)

◼️动态代理及实现方式

静态

java代理_第7张图片

要实现动态问题在于如何让一个类生成不同类的对象,但ABC理论上是相同的 因为同一类对象有相同的类模板。

为什么让不同的代理对象代理不同的类? 便于添加新的目标类(例如新添加袜子工厂时无需再去改动代理类,而是通过添加新的代理对象来实现)

动态代理:生成不同的代理对象,每一个代理对象都代理着自己的目标对象(术业有专攻)

java代理_第8张图片

java代理_第9张图片

代码

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 动态代理类
 * 1、目标类的引用
 * 2、调用目标类的核心方法,并实现功能的增强
 * 核心方法在于目标类实现的接口当中
 * 如何找到目标类的接口-------》反射(找到类信息)
 */
public class Agent_Dynamic implements InvocationHandler{
    //1、目标类的引用   与静态相比较灵活
    private Object factory;
    public Agent_Dynamic(Object factory){
        this.factory=factory;
    }

    //反射找到目标类接口
    public Object getProxyInterface(){
        return Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(), (InvocationHandler) this);
    }
    /**
     * 如何调用核心方法?? -----》 jdk(java的开发者)给我们提供了调用核心方法的接口
     * @param proxy
     * @param method   通过反射带来的核心方法
     * @param args     核心方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("----前期准备----");
        method.invoke(factory,args);   //invoke里边是对象和参数
        System.out.println("----打包发货----");
        return null;
    }
}
/**
*客户
*/
public class Person {
    public static void main(String[] args) {
        ClothesFactory clothesFactory=new ClothesFactory();
        Clothes proxy1=(Clothes) new Agent_Dynamic(clothesFactory).getProxyInterface();  //生成代理类对象
        proxy1.byClothes("xxl");

        ShootFactory shootFactory=new ShootFactory();
        Shoot proxy2=(Shoot) new Agent_Dynamic(shootFactory).getProxyInterface();
        proxy2.byShoot("37");
    }
}

(接口 工厂类与静态代理相同)

java代理_第10张图片

你可能感兴趣的:(java,开发语言)