动态代理模式基础讲解(包括静态代理模式)

本文介绍了代理模式的基本概念,以及静态代理和动态代理的原理。在静态代理中,代理类和被代理类需要实现相同的接口,代理类在调用被代理类方法时可以进行额外操作。动态代理则在运行时动态生成代理对象,解决了静态代理的扩展性和灵活性问题,适用于调试、远程调用等场景。Java中动态代理通过`Proxy.newProxyInstance()`方法实现,需要传递被代理对象的类加载器、接口数组和`InvocationHandler`的实现类。
摘要由CSDN通过智能技术生成

代理模式

1、原理(百度)
代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。

2、静态代理模式

原理讲解

  1. 代理类与被代理类都必须实现同一个接口。
  2. 代理类对被代理类进行封装,由代理类决定 被代理类的对象的创建、创建时间、何时调用方法。
  3. 被代理类的方法调用放在代理类中执行。
  4. 代理类中执行被代理类的方法时可以进行其他操作。

实现同一个 接口
以手机厂商为例:
现在有一个手机工厂的接口

public interface PhoneFactory {
    void producePhone();//生产一批手机
}

现在有两个实现类:代理类与被代理类都实现了PhoneFactory接口
1、代理类ProxyFactory

//代理类
public class ProxyFactory implements PhoneFactory{

    private PhoneFactory factory;//被代理类对象进行实例化

    public ProxyFactory(PhoneFactory factory) {
        this.factory = factory;
    }
    @Override
    public void producePhone() {
        System.out.println("代理工厂做前期准备工作");
        factory.producePhone();
        System.out.println("代理工厂的后期工作");
    }
}

2、被代理类MiFactory

//被代理类
public class MiFactory implements PhoneFactory{
    @Override
    public void producePhone() {
        System.out.println("生产一批手机");
    }
}

3、静态代理模式实现:

public class Test {
    public static void main(String[] args) {
        MiFactory mi = new MiFactory();//创建被代理类对象
        ProxyFactory proxyFactory = new ProxyFactory(mi);//创建代理类的对象
        proxyFactory.producePhone();//代理类对象对被代理类方法的封装与其他处理
    }
}

结果:
在这里插入图片描述
静态代理过程描述:

  1. 创建被代理类的对象
  2. 将被代理类的对象mi 传入 代理类的实例化对象 proxyFactory 中
  3. 在proxyFactory 调用同名方法 (实际上时调用代理类的对象mi 的方法,在proxyFactory 中进行其他操作。

三、动态代理模式

1、静态代理存在的问题:
代理类和目标对象的类都是在编译期间确认下来,不利于程序的扩展。
同时,每一个代理类只能为一组接口服务,
这样一来程序开发中必然产生过多的代理。
2、动态代理模式说明:
①动态代理时指客户通过代理类来调用其他对象的方法,并且时在程序运行时根据需要动态的创建目标类的代理对象。
②动态代理使用的场合:

  • 调试
  • 远程方调用

优点:
抽象角色中(接口)声明的所有方法都被转移到调试处理器一个集中的方法中处理,这样,我们可以更灵活和统一的处理众多的方法
3、代码举例说明
首先,我们需要创建一个共同的接口。(以Human为例)

public interface Human {
    String getBelief();//获取信仰的方法
    void eat(String food);//吃的方法
}

其次,我们需要一个代理类

public class DynamicProxy {
	//调用此方法 动态的创建代理类的对象 
	//参数为 被代理类的对象
    public static Object getInstance(Object obj){
        MyInvocationHandler handler = new MyInvocationHandler(obj);//InvocationHandler接口的实现类
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler );
    }
}

Proxy.newProxyInstance();
Proxy是 java.lang.reflect.Proxy;
.newProxyInstance(); // 方法会使用反射的原理 动态的生成一个对象
方法的三个参数
在这里插入图片描述
obj.getClass().getClassLoader() // 获取被代理类的Class类的类加载器
obj.getClass().getInterfaces() // 获取被代理类的Class类的接口数组

InvocationHandler的实现类

//InvocationHandler的实现类
public class MyInvocationHandler implements InvocationHandler {
    private Object obj;//需要一个被代理类的对象
    //构造器
    public MyInvocationHandler(Object obj) {
        this.obj = obj;
    }
    /**
     *当我们通过代理类调用方法时 会自动的调用如下方法 
     * invoke(Object proxy, Method method, Object[] args);
     * Object proxy代理类
     * Method method 被调用方法
     * Object[] args 参数列表
     * returnValue 返回值
     **/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object returnValue = method.invoke(obj, args);
        return returnValue;
    }
}

最后,我们需要一个被代理类

//被代理类
public class SuperMan implements Human{
    @Override
    public String getBelief() {
        return "I believe i can fly";
    }
    @Override
    public void eat(String food) {
        System.out.println("我喜欢一直吃"+food);
    }
}

动态代理模式实现:

public class test {
    public static void main(String[] args) {
    	//创建被代理类的对象
        SuperMan superMan = new SuperMan();
        Human proxy = (Human) DynamicProxy.getInstance(superMan);//动态的创建代理类的对象
        //调用方法
        proxy.eat("小鱼");
        String belief = proxy.getBelief();
        System.out.println(belief);
    }
}

结果:
在这里插入图片描述
动态代理过程说明

  1. 代理类的动态创建需要 传入 被代理类的对象,

  2. 通过getInstance()方法返回一个代理类的对象

  3. Proxy.newProxyInstance()方法需要三个参数 (代理类的对象的类加载器,代理类的对象的接口集合,InvocationHandler的实现类);

  4. InvocationHandler接口的主要作用是将代理类与被代理类进行链接。

  5. 正因为需要连接 所以我们需要传入被代理类的对象
    InvocationHandler接口的实现类需要实现
    invoke方法 (Object proxy, Method method,Object[] args)
    proxy 代理类
    method 将被调用的方法
    args 被调用的方法 的参数数组

  6. invoke方法 中调用 被代理类的对象的invoke方法即可实现代理模式

  7. InvocationHandler接口的实现类的invoke方法 中 可以增加其他操作

  8. InvocationHandler接口的实现类作为Proxy.newProxyInstance()方法的参数,进行绑定 当调用代理类的方法时会自动的调用InvocationHandler接口的实现类的invoke方法,实现动态代理

如有什么错误,请联系我一下撒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值