【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )

简介: 【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )

文章目录

前言

一、静态代理的弊端

二、动态代理的优势

三、动态代理使用流程

1、目标对象接口

2、被代理对象

3、调用处理程序

4、客户端

四、动态生成 代理对象 类 的 字节码 文件数据

前言

代理模式结构 : 代理模式中的元素有 客户端 , 主题对象 , 被代理对象 , 代理对象 ;


客户端 持有 主题对象 , 调用其方法 ;

代理对象 和 被代理对象 都是 主题 的子类 ;

代理对象 持有 被代理对象 , 可以调用 被代理对象 的方法 ;

image.png


代理模式的核心 : 代理对象 与 被代理对象 都实现同一个父类或接口 , 这样在客户端使用时 , 客户端 感觉自己与 被代理对象 沟通 , 但用户实际上与 代理对象 进行沟通 ;






一、静态代理的弊端


静态代理 中 , 代理对象 和 被代理对象 必须实现 主题对象 接口 , 如果 主题对象 接口发生改变 , 则相应的 代理对象 和 被代理对象 都要进行相应修改 ;






二、动态代理的优势


动态代理 解决了 静态代理的上述问题 , 不需要手动创建代理对象 , 由 Java 虚拟机实现 代理对象 , 该代理对象自动实现 主题对象 的接口 ;


动态代理执行时 , 动态地创建了字节码文件 , 生成了代理类 ;






三、动态代理使用流程


动态代理使用流程 :


① 创建目标对象 : 创建 目标对象 接口 ;


② 创建被代理对象 : 创建 被代理对象 , 实现 目标对象 接口 ;


③ 创建调用处理程序 : 创建 InvocationHandler 子类对象 , 内部持有 被代理对象 , 在 invoke 方法中 , 返回 method.invoke(subject, args) ;


④ 动态创建代理对象 : 调用 Proxy.newProxyInstance 创建 代理对象 实例对象 , 由 JVM 自动创建代理对象类 , 然后再创建对应的实例对象 ;


⑤ 动态代理调用 : 调用 代理对象 实例的相关 目标对象 接口 方法 ;



1、目标对象接口

/**
 * 目标接口
 *  代理对象 和 被代理对象 都要实现该接口
 */
public interface Subject {
    void request();
}



2、被代理对象


/**
 * 被代理对象
 */
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("被代理对象 RealSubject request()");
    }
}



3、调用处理程序


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicInvocationHandler implements InvocationHandler {
    /**
     * 持有的 被代理对象
     */
    private Subject subject;
    public DynamicInvocationHandler(Subject subject) {
        this.subject = subject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 调用真实的 被代理对象 的方法
        //  被代理对象的所有的方法的调用都会传到该方法中进行处理
        Object object = method.invoke(subject, args);
        return object;
    }
}



4、客户端


import java.lang.reflect.Proxy;
public class Client {
    public static void main(String[] args) {
        // 被代理对象
        Subject realSubject = new RealSubject();
        // 创建调用处理程序 , 内部持有被代理对象
        DynamicInvocationHandler dynamicInvocationHandler =
                new DynamicInvocationHandler(realSubject);
        // 生成动态代理类
        Subject subject = (Subject) Proxy.newProxyInstance(
                realSubject.getClass().getClassLoader(),
                realSubject.getClass().getInterfaces(),
                dynamicInvocationHandler);
        // 动态代理调用
        subject.request();
    }
}


执行结果 :

image.png







四、动态生成 代理对象 类 的 字节码 文件数据


动态代理 中的 代理对象对应的 字节码类 是由 Java 虚拟机自动生成的 , 在 java.lang.reflect.Proxy 中 , 调用 ProxyGenerator.generateProxyClass 方法 , 生成了 代理对象 类 , 返回的 byte[] 数据就是字节码类对应的二进制数据 ;


       

/*
             * Generate the specified proxy class.
             */
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);



ProxyGenerator 的源码需要下载 JDK 源码查看 , 在 IntelliJ IDEA 开发环境中无法查看 ;


网上找到了一篇博客 , 对此描述的很清楚 JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析 ;


ProxyGenerator 中的 generateProxyClass 方法中 , 主要调用了 generateClassFile 方法 , 按照 Class 字节码的规范 , 按照顺序依次写入 魔数 , 次版本号 , 主版本号 , 常量池 , 访问修饰符 , 类索引 等数据 ;


目录
相关文章
|
6天前
|
设计模式 缓存 安全
设计模式——代理模式
静态代理、JDK动态代理、Cglib 代理
设计模式——代理模式
|
1月前
|
设计模式 缓存 Java
【十一】设计模式~~~结构型模式~~~代理模式(Java)
文章详细介绍了代理模式(Proxy Pattern),这是一种对象结构型模式,用于给对象提供一个代理以控制对它的访问。文中阐述了代理模式的动机、定义、结构、优点、缺点和适用环境,并探讨了远程代理、虚拟代理、保护代理等不同代理形式。通过一个商务信息查询系统的实例,展示了如何使用代理模式来增加身份验证和日志记录功能,同时保持客户端代码的无差别对待。此外,还讨论了代理模式在分布式技术和Spring AOP中的应用,以及动态代理的概念。
【十一】设计模式~~~结构型模式~~~代理模式(Java)
|
1月前
|
设计模式
设计模式的基础问题之代理模式在工作中的问题如何解决
设计模式的基础问题之代理模式在工作中的问题如何解决
|
1月前
|
设计模式 Java API
设计模式-------------静态/动态代理模式(结构型设计模式)
本文详细介绍了代理模式,包括其定义、应用场景、UML类图、代码实现和实际例子,阐述了静态代理和动态代理的区别以及它们的优缺点,展示了如何通过代理模式来控制对目标对象的访问并增强其功能。
|
1月前
|
设计模式 存储 安全
18 Java反射reflect(类加载+获取类对象+通用操作+设计模式+枚举+注解)
18 Java反射reflect(类加载+获取类对象+通用操作+设计模式+枚举+注解)
62 0
|
2月前
|
设计模式 算法 Go
iLogtail设计模式问题之代理模式在iLogtail中是如何应用的
iLogtail设计模式问题之代理模式在iLogtail中是如何应用的
|
2月前
|
设计模式
iLogtail设计模式问题之iLogtail工厂模式下的实践流程是啥样的
iLogtail设计模式问题之iLogtail工厂模式下的实践流程是啥样的
|
2月前
|
存储 算法 调度
iLogtail设计模式问题之如何确定定时任务框架的功能边界和目标
iLogtail设计模式问题之如何确定定时任务框架的功能边界和目标
|
6天前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
1月前
|
设计模式
设计模式-单一职责模式
设计模式-单一职责模式