【设计模式】 代理模式(静态代理、动态代理{JDK动态代理、JDK动态代理与CGLIB动态代理的区别})

代理模式

代理模式是一种结构型设计模式,它提供了一种替代访问的方法,即通过代理对象来间接访问目标对象。代理模式可以在不改变原始类代码的情况下,增加额外的功能,如权限控制、日志记录等。

静态代理

静态代理是指创建的或特定工具自动生成源代码,在程序运行前代理类的.class文件就已经存在了。每个代理类只能为一个接口服务,如果需要代理多个接口,则需要编写多个代理类,这会增加维护成本。

示例:房子中介(静态代理)
// 房屋租赁服务接口
interface HouseLeaseService {
    void leaseHouse();
}

// 真实主题类 - 房东
class Landlord implements HouseLeaseService {
    public void leaseHouse() {
        System.out.println("房东: 出租房屋.");
    }
}

// 静态代理类 - 中介
class RealEstateAgent implements HouseLeaseService {
    private Landlord landlord;

    public RealEstateAgent(Landlord landlord) {
        this.landlord = landlord;
    }

    @Override
    public void leaseHouse() {
        // 增加额外功能,例如广告宣传
        System.out.println("中介: 发布租房信息.");
        landlord.leaseHouse();
        // 增加额外功能,例如收取中介费
        System.out.println("中介: 收取中介费用.");
    }
}

public class StaticProxyDemo {
    public static void main(String[] args) {
        Landlord landlord = new Landlord();
        HouseLeaseService agentService = new RealEstateAgent(landlord);
        agentService.leaseHouse();
    }
}

在这个例子中,RealEstateAgent作为代理类,不仅实现了HouseLeaseService接口,还包含了对Landlord对象的操作,并在调用前后添加了额外的行为。

动态代理

动态代理是在程序运行时动态生成代理类的字节码并加载到JVM中,因此不需要提前编写代理类的代码。Java提供了两种主要的动态代理方式:JDK动态代理和CGLIB。

JDK动态代理

在JDK动态代理中有两个重要的类ProxyInvocationHandler

  • Proxy
    Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
    在这里插入图片描述
    在这里插入图片描述

  • InvocationHandler
    InvocationHandler 是代理实例的调用处理程序 实现的接口。
    每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
    在这里插入图片描述

代码示例

首先,我们定义一个实现了InvocationHandler接口的处理器类ProxyInvocationHandler ,它负责封装中介的具体业务逻辑。

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

// 房屋租赁服务接口
interface HouseLeaseService {
    void leaseHouse();
}

// 真实主题类 - 房东
class Landlord implements HouseLeaseService {
    public void leaseHouse() {
        System.out.println("房东: 出租房屋.");
    }
}

// 实现InvocationHandler接口的处理器类 - 中介
class ProxyInvocationHandler implements InvocationHandler {
    private final Object target;

    public ProxyInvocationHandler(Object target) {
        this.target = target;   
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 在调用真实方法之前可以做一些额外的工作
        System.out.println("中介: 发布租房信息.");
        
        // 调用目标对象的方法
        Object result = method.invoke(target, args);
        
        // 在调用真实方法之后也可以做一些额外的工作
        System.out.println("中介: 收取中介费用.");
        
        return result;
    }
}

public class JdkProxyDemo {

    public static void main(String[] args) {
        // 创建真实房东对象
        Landlord landlord = new Landlord();

        // 创建动态代理实例
        HouseLeaseService proxyInstance = (HouseLeaseService) Proxy.newProxyInstance(
                landlord.getClass().getClassLoader(),
                landlord.getClass().getInterfaces(),
                new ProxyInvocationHandler(landlord)
        );

        // 通过代理实例调用方法
        proxyInstance.leaseHouse();
    }
}

JDK动态代理与CGLIB动态代理的区别

特性JDK 动态代理CGLIB 动态代理
实现方式只能代理实现了接口的类(基于接口)通过生成目标类的子类进行代理(基于继承)
代理类- Proxy
- Invocation Handler
- Enhancer
- Method Interceptor
核心机制使用反射调用目标方法通过ASM字节码生成目标类的子类,重写方法实现代理
性能 (jdk8)在一百万运行次数内,性能快了30%左右;到五百万运行次数后,性能快了将近一倍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/971930.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习之图像回归(二)

前言 这篇文章主要是在图像回归(一)的基础上对该项目进行的优化。(一)主要是帮助迅速入门 理清一个深度学习项目的逻辑 这篇文章则主要注重在此基础上对于数据预处理和模型训练进行优化前者会通过涉及PCA主成分分析 特征选择 后…

利用分治策略优化快速排序

1. 基本思想 分治快速排序(Quick Sort)是一种基于分治法的排序算法,采用递归的方式将一个数组分割成小的子数组,并通过交换元素来使得每个子数组元素按照特定顺序排列,最终将整个数组排序。 快速排序的基本步骤&#…

照片模糊怎么变清晰?图生生AI修图-一键清晰放大

当打开手机相册时,那些泛着噪点的合影、细节模糊的风景照、像素化的证件图片,让珍贵时刻蒙上遗憾的面纱。而专业级图像修复工具的门槛,让多数人只能无奈接受这些"不完美的记忆"。AI技术的发展,让普通用户也能轻松拥有专…

Linux 网络与常用操作(适合开发/运维/网络工程师)

目录 OSI 七层协议简介 应用层 传输层 Linux 命令!!! 1. ifconfig 命令 简介 1. 查看网络地址信息 2. 指定开启、或者关闭网卡 3. 修改、设置 IP 地址 4. 修改机器的 MAC 地址信息 5. 永久修改网络设备信息 2. route 路由命令 …

PID控制学习

前言 本篇文章属于PID控制算法的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。 PID入门教程-电机控制 倒立摆 持续更新中_哔哩哔哩_bilibili 一…

第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式

第1期 定时器实现非阻塞式程序 按键控制LED闪烁模式 解决按键扫描,松手检测时阻塞的问题实现LED闪烁的非阻塞总结补充(为什么不会阻塞) 参考江协科技 KEY1和KEY2两者独立控制互不影响 阻塞:如果按下按键不松手,程序就…

【Arxiv 大模型最新进展】PEAR: 零额外推理开销,提升RAG性能!(★AI最前线★)

【Arxiv 大模型最新进展】PEAR: 零额外推理开销,提升RAG性能!(★AI最前线★) 🌟 嗨,你好,我是 青松 ! 🌈 自小刺头深草里,而今渐觉出蓬蒿。 NLP Github 项目…

vscode的一些实用操作

1. 焦点切换(比如主要用到使用快捷键在编辑区和终端区进行切换操作) 2. 跳转行号 使用ctrl g,然后输入指定的文件内容,即可跳转到相应位置。 使用ctrl p,然后输入指定的行号,回车即可跳转到相应行号位置。

OAI 平台 4G(LTE)基站 、终端、核心网 端到端部署实践(一)

本系列文章,基于OAI LTE代码搭建端到端运行环境,包含 eNB,EPC,UE三个网元。本小节先介绍系统总体架构,硬件平台及驱动安装方法。 1. Overview 系统总体架构如下图所示。 2 Machine setup 2.1 Machine specs Distributor ID: Ubuntu Description: Ubuntu 18.04.5 LTS…

Linux环境Docker使用代理推拉镜像

闲扯几句 不知不觉已经2月中了,1个半月忙得没写博客,这篇其实很早就想写了(可追溯到Docker刚刚无法拉镜像的时候),由于工作和生活上的事比较多又在备考软考架构,拖了好久…… 简单记录下怎么做的&#xf…

基于TI的TDA4高速信号仿真条件的理解 4.6

Application Note 《Jacinto7 AM6x, TDA4x, and DRA8x High-Speed Interface Design Guidelines》 4.6 Reviewing Simulation Results检查仿真结果 The results generated by the channel simulations outlined in the preceding sections are compared against an eye mask s…

unity学习46:反向动力学IK

目录 1 正向动力学和反向动力学 1.1 正向动力学 1.2 反向动力学 1.3 实现目标 2 实现反向动力 2.1 先定义一个目标 2.2 动画层layer,需要加 IK pass 2.3 增加头部朝向代码 2.3.1 专门的IK方法 OnAnimatorIK(int layerIndex){} 2.3.2 增加朝向代码 2.4 …

DeepSeek 和 ChatGPT 在特定任务中的表现:逻辑推理与创意生成

🎁个人主页:我们的五年 🔍系列专栏:Linux网络编程 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 ​ Linux网络编程笔记: https://blog.cs…

DAY07 Collection、Iterator、泛型、数据结构

学习目标 能够说出集合与数组的区别数组:1.是引用数据类型的一种2.可以存储多个元素3.数组的长度是固定的 int[] arr1 new int[10]; int[] arr2 {1,2,3};4.数组即可以存储基本类型的数据,又可以存储引用数据类型的数据int[],double[],String[],Student[]集合:1.是引用数据类…

ls命令的全面参数解析与详尽使用指南

目录 ls 命令的所有参数及含义 ls -a 命令详解 ls -A 命令详解 ls -b 命令详解 ls -C 命令详解 ls -d 命令详解 ls -f 命令详解 ls -F 命令详解 ls -G 命令详解 ls -h 命令详解 ls -H 命令详解 ls -i 命令详解 ls -I 命令详解 ls -l 命令详解 ls -L 命令详解 l…

【Spring+MyBatis】_图书管理系统(中篇)

【SpringMyBatis】_图书管理系统(上篇)-CSDN博客文章浏览阅读654次,点赞4次,收藏7次。(1)当前页的内容records(类型为List);参数:userNameadmin&&pas…

动态规划算法篇:枚举的艺术

那么本篇文章就正式进入了动态规划的算法的学习,那么动态规划算法也可谓是算法内容中的一座大山,那么在大厂算法笔试乃至算法比赛中出现的频率也逐渐变高,那么可见学习好动态规划算法的一个重要性,那么对于动态规划最难理解的&…

算法——舞蹈链算法

一,基本概念 算法简介 舞蹈链算法(Dancing Links,简称 DLX)是一种高效解决精确覆盖问题的算法,实际上是一种数据结构,可以用来实现 X算法,以解决精确覆盖问题。由高德纳(Donald E.…

翻转硬币(思维题,巧用bitset)

0翻转硬币 - 蓝桥云课 #include <bits/stdc.h> using namespace std; bitset<200000001> t; int main() {int n;cin>>n;int ans1;t[1]1;int totn-1;for(int i2;i<n;i){if(t[i]) continue;int ji;ans;while(j<n){t[j]!t[j];if(t[j]) tot--;else tot;ji;…

网络安全等级保护测评(等保测评):全面指南与准备要点

等保测评&#xff0c;全称为“网络安全等级保护测评”&#xff0c;是根据《网络安全法》及《网络安全等级保护条例》等法律法规&#xff0c;对信息系统进行安全等级划分&#xff0c;并依据不同等级的安全保护要求&#xff0c;采用科学方法和技术手段&#xff0c;全面评估信息系…