美文网首页
Retrofit网络框架2:静态代理+动态代理

Retrofit网络框架2:静态代理+动态代理

作者: xqiiitan | 来源:发表于2025-09-05 14:16 被阅读0次

Retrofit 动态代理详解。

代理

代替别人,去做我们想做的事情。
代理模式:为其他对象提供一种代理,用以控制对这个对象的访问。
eg:海外购物。过程有朋友在海外购买,最终结果是收到商品,只在意结果 不在意购买过程。

1.静态代理

抽象对象 AbstractObject 有 operation()接口。
代理对象 ProxyObject 有 operation()方法,且持有realObject对象的引用。
真实对象 RealObject 有 operation()方法。

代理对象,将客户端的调用,委派给了目标对象RealObject,
在调用目标对象之前和之后,都可以添加某些特定操作。
可对产生的结果进行一定的控制。

// 1.代理的抽象类,要被代理类和 目标类 需要共同继承。
public abstract class AbstractObject { //【抽象类】。
    //抽象方法。共同抽象接口
    protected abstract void operation();
}
//2.目标对象的实现类,继承自AbstractObject 抽象类。
public class RealObject extends AbstractObject {
    @Override
    protected void operation() {
        System.out.println("do operation...");
    }
}

//3.----静态代理,代理类角色----
public class ProxyObject extends AbstractObject {
    // 3.0 对目标类的引用,有统一的接口。可以在任何时候替换目标对象。
    private RealObject realObject;
    public ProxyObject(RealObject realObject) { //替换目标类
        this.realObject = realObject;
    }
    @Override
    protected void operation() { //代理自己的operation
        //3.1 在调用目标对象前面添加东西。可以加自己的判断逻辑
        System.out.println("do something before real peration...");
        if (realObject == null) {
            realObject = new RealObject();
        }
        //3.2 委派给了目标对象。调用目标对象的方法。
        realObject.operation(); 
        //3.3 在调用目标对象后面添加东西。可以加自己的判断逻辑
        System.out.println("do something after real operation...");
    }
}
public class Test {
    public static void main(String[] args) {
        // 最终对象
        RealObject realObject = new RealObject();
        // 代理对象
        ProxyObject proxyObj = new ProxyObject(realObject);
        proxyObj.operation();
    }
}
//最终输出:
// do something before real peration...
// do operation...
// do something after real operation...

使用场景:

对已有方法做改进,故建议修改原有的方法,可以使用静态代理。
可以采用代理类,调用原来的方法,对产生的结果进行控制。
使用代理模式,能将功能划分的更加清晰,让代码维护更加便捷。


2.动态代理【重要】【为接口创建代理】

优势:‘无侵入’式的拓展代码,增强一些方法和功能。在方法的前后,可以做任何想做的事情。
动态代理: 代理类在程序运行时,创建的代理方式。

相比于静态代理:
优势,他能很方便的对代理类的函数,进行统一的处理。而不用频繁的去修改每一个代理类的函数。
两种动态代理:jdk动态代理(java内部的反射机制,生成类的过程中高效); CGLIB动态代理.
在不改变原来代码的情况下,在调用的前后添加代码。
jdk中的代理,只能为接口创建代理。

2.0 拦截

1.每个代理类的对象都会关联一个表示内部处理逻辑的 InvocationHandler 接口的实现;
当使用者调用了代理对象所代理的接口中的方法时,这个调用的信息 就会传递到 InvocationHandler的invoke方法;
2.invoke方法的参数中 可以获取参数(3个参数)
3.invoke方法的返回值 将返回给使用者。

2.1 代码部分

//1. 抽象接口类
public interface Subject{
    void shopping();
}
//2.目标类
public class Man implements Subject {
    @Override
    public void shopping() {
        System.out.println("Mjj"+"要去买东西...");
    }
}
//3.代理类。继承自InvocationHandler,并实现其invoke方法。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Proxy implements InvocationHandler {
    private Object target;//要代理的真实对象
    public Proxy(Subject target){
        this.target = target;
    }
    //代理对象调用程序的时候,所一定要实现的接口,当通过代理对象调用方法的时候,
    //这个方法就会把它指派到它调用处的 InvocationHandler的invoke 方法上.
    //proxy 指代的真实对象,可理解为真实对象的一个代理;
    //method 真实对象的方法;
    //args 所代理真实对象的 某个方法的 所有参数.
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy:" + proxy.getClass().getName());
        System.out.println("before...");
        method.invoke(target, args); //通过反射执行方法
        System.out.println("after...");
        return null;
    }
}
//4.测试类
public class Client {
    public static void main(String[] args) {
        Subject man = new Man();
        Proxy p = new Proxy(man);
        //4.1 【重点】通过java.lang.reflect.newProxyInstance(...)方法获得真实对象的代理对象
        //-类加载器,把动态生成的代理的字节码文件加载到jvm虚拟机当中。一般使用被代理类的类加载器。
        //-getInterfaces() 为代理对象提供的接口,就是被代理实现的接口;
        //  public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
        //-p:当代理对象调用方法的时候,关联到InvocationHandler,然后调用里面的 invoke方法。
        Subject subject = (Subject)java.lang.reflect.Proxy.newProxyInstance(man.getClass().getClassLoader(),
                        man.getClass().getInterfaces(), p);
        //通过代理对象调用真实对象相关接口中实现的方法,这个时候就会跳转到这个代理对象所关联的handler的invoke()方法去执行
        subject.shopping();
        //获得真实对象的代理对象所对应的Class对象的名称,用字符串表示
        System.out.println(subject.getClass().getName());
    }
}
// Proxy中,关联InvocationHandler
public class Proxy implements java.io.Serializable {
    /**
     * the invocation handler for this proxy instance.
     */
    protected InvocationHandler h;
}

Subject subject = (Subject)java.lang.reflect.Proxy.newProxyInstance(man.getClass().getClassLoader(),
                        man.getClass().getInterfaces(), p);
// 根据传递的class对象,生成对象A(代理类),每当代理A执行某个方法的时候,                        
他就会调用第三个参数 InvocationHandler 的invoke() 方法。
在这个方法中,可以执行响应的操作。 这就是jdk动态代理的全过程。                       

总结:
1.运行期,动态代理 他是通过代理类与相关接口不直接发生联系的情况下,而在运行时实现动态关联;
2.InvocationHandler 接口 与 Proxy类(反射包中)。
3.动态代理与静态代理最大的不同:动态代理的代理类,不需要手动生成,
该代理类是根据配置在运行期间动态生成的(不是hardCode,是运行期动态生成的)。
这个动态生成的代理类,已经实现了代理对象的相关接口,

----------End------------------------

相关文章

  • Java高级主题(五)——动态代理

    代理可以分为静态代理、动态代理,动态代理又可以分为 jvm的动态代理 和 cglib的动态代理。像spring框架...

  • 编程常用的设计模式

    动态代理和静态代理 静态代理 动态代理 静态代理与动态代理的区别 JDK中的动态代理和CGLIB 实现动态代理的方...

  • 代理模式

    1,静态代理 2,动态代理

  • #Java动态代理

    Java动态代理 retrofit是一个解耦性非常高的网络请求框架,最近在研究的时候发现了动态代理这个非常强大且实...

  • java代理(proxy)

    静态代理 JDK 动态代理 CGLib 动态代理1)引入maven依赖 2)代码实现

  • JAVA动态代理的实现方式

    1. 静态代理VS动态代理 代理类可以增强被代理对象的方法。可分为静态代理和动态代理。 1.1 静态代理 静态代理...

  • 带你初识Java的代理模式

    Spring AOP是基于动态代理设计模式实现的,相对的就有静态代理 动态代理和静态代理 静态代理 对于静态代理,...

  • Retrofit的原理

    Retrofit是目前比较流行的网络框架,它封装了okhttp作为底层的网络通讯框架, 使用动态代理方式来解析注...

  • Retrofit的内核原理解析

    简介 Retrofit是目前比较流行的网络框架,它封装了okhttp作为底层的网络通讯框架, 使用动态代理方式来解...

  • Java动态代理-执行过程

    1,静态代理 1)静态代理image.pngimage.png 2,动态代理 1)newProxyInstance...

网友评论

      本文标题:Retrofit网络框架2:静态代理+动态代理

      本文链接:https://www.haomeiwen.com/subject/msrbajtx.html