【设计模式--结构型--代理模式】

设计模式--结构型--代理模式

    • 代理模式
      • 概述
      • 结构
      • 静态代理案例:卖车票
      • jdk动态代理
      • cglib代理
      • 三种代理对比
      • 优缺点
      • 使用场景

代理模式

概述

由于某些原因需要给某对象提供一个代理以控制该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
java中的代理机制分为静态代理和动态代理

  • 静态代理:代理类在在编译期就生成
  • 动态代理:代理类在java运行时动态生成。
    • JDK代理
    • CGLib代理

结构

代理模式分为三种角色:

  • 抽象主题类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • 真实主题类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 代理类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

静态代理案例:卖车票

市面上任何卖火车票软件都是通过12306来买的,这就是一个典型的代理模式,12306是目标对象,其他售票软件是代理对象。
在这里插入图片描述

public class ProxyPoint implements SellTicket{

    // 声明12306类对象
    private TrainStation trainStation = new TrainStation();

    @Override
    public void sell() {
        System.out.println("其它app买票---可以增强");
        trainStation.sell();
    }
}
/**
 * 卖火车票的接口
 */
public interface SellTicket {
    void sell();
}
public class TrainStation implements SellTicket{
    @Override
    public void sell() {
        System.out.println("12306卖火车票");
    }
}
public class Test01 {
    public static void main(String[] args) {
        ProxyPoint proxyPoint = new ProxyPoint();
        proxyPoint.sell();
    }
}

从上面代码中可以看出测试类是直接访问ProxyPoint类对象,也就是说ProxyPoint作为目标访问对象和目标对象的中介,同时也对sell方法进行了增强。

jdk动态代理

接下来使用动态代理实现上面案例,java中提供了一个动态代理类Proxy,Proxy并不是我们上面说的代理对象类,
而是提供了一个创建代理对象的静态方法(newProxyInstance)来获取代理对象。

/**
 * 获取代理对象的工厂类
 * 代理类也实现了对应的接口
 */
public class ProxyFactory {
    // 声明目标对象
    private TrainStation station = new TrainStation();
    public SellTicket getProxyObject(){
        /**
         * ClassLoader loader 类加载器,用于加载代理类。可以通过目标对象获取类加载器
         * Class<?>[] interfaces 代理类实现的接口的字节码对象
         * InvocationHandler h 代理对象的调用处理程序
         */
        SellTicket proxyObject = (SellTicket) Proxy.newProxyInstance(
                station.getClass().getClassLoader(),
                station.getClass().getInterfaces(),
                /**
                 * Object proxy:代理对象,和proxyObject对象是同一个对象
                 * Method method:对接口中的方法进行封装的method对象
                 * Object[] args:调用方法的实际参数
                 * 返回值:方法的返回值
                 */
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //
                        System.out.println("代售app---增强");
                        // 执行目标对象的方法
                        return method.invoke(station, args);
                    }
                }
        );
        return proxyObject;
    }
}
/**
 * 卖火车票的接口
 */
public interface SellTicket {
    void sell();
}

cglib代理

/**
 * 代理对象工厂,用来获取代理对象
 */
public class ProxyFactory implements MethodInterceptor {

    private TrainStation station = new TrainStation();

    public TrainStation getProxyObject(){
        // 创建Enhancer对象,类似jdk代理中的Proxy类
        Enhancer enhancer = new Enhancer();
        // 设置父类的字节码对象
        enhancer.setSuperclass(TrainStation.class);
        // 设置回调函数
        enhancer.setCallback(this);
        // 创建代理对象
        TrainStation proxyObject = (TrainStation) enhancer.create();
        return proxyObject;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib代理");
        // 要调用目标对象的方法
        TrainStation invoke = (TrainStation) method.invoke(station, objects);
        return invoke;
    }
}
public class TrainStation {
    public void sell() {
        System.out.println("12306卖火车票");
    }
}
public class Test02 {
    public static void main(String[] args) {
        // 创建代理工厂对象
        ProxyFactory factory = new ProxyFactory();
        // 获取代理对象
        TrainStation proxyObject = factory.getProxyObject();
        // 调用代理对象中的sell方法
        proxyObject.sell();
    }
}

三种代理对比

  • jdk代理和cglib代理
    • 使用CGLib实现动态代理,cglib底层采用ASM字节码生产框架,使用字节码技术生成代理类,在jdk1.6之前比使用java反射效率要高。
      唯一需要注意的是:cglib不能对声明为final的类或方法进行代理,因为cglib原理是动态生成被代理的子类。

      在jdk1.8对jdk动态代理优化后,jdk代理效率高于cglib代理,如果有接口使用jdk代理,没有接口使用cglib代理。

  • 动态代理和静态代理
    • 动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法处理(InvocationHandler.invoke)。这样在接口
      方法数量比较多的时候,我们可以灵活处理,而不需要像静态代理那样每一个方法进行中转。
      如果接口增加一个方法,静态代理模式处理实现所有类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。而动态代理不会出现该问题

优缺点

  • 优点:
    • 代理模式在客户端与目标对象之间起到了一个中介作用和保护作用
    • 代理对象可以扩展目标对象的功能
    • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度
  • 缺点:
    • 增加了系统的复杂度

使用场景

  • 远程代理
    • 本地服务通过网络请求远程服务。为了实现本地到远程的通信,我们需要实现网络通信,处理其中可能的异常。为良好的代码设计和可维护性,
      我们将网络通信部分隐藏起来,只暴露给本地服务一个接口,通过该接口即可访问远程服务提供的功能,而不必过多关心通信部分的细节。
  • 防火墙代理
    • 将浏览器配置成使用代理功能时,防火墙就可以将浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把他转给你的浏览器。
  • 保护代理
    • 控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。

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

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

相关文章

Postgresql中PL/pgSQL的游标、自定义函数、存储过程的使用

场景 Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句&#xff1a; Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句-CSDN博客 上面讲了基本语法&#xff0c;下面记录游标、自定义函数、存储过程的使用。 …

智能化物联网(IoT):发展、问题与未来前景

导言 智能化物联网&#xff08;IoT&#xff09;作为信息技术领域的一项核心技术&#xff0c;正在深刻改变人们的生活和工作方式。本文将深入研究IoT的发展过程、遇到的问题及解决过程、未来的可用范围&#xff0c;以及在各国的应用和未来的研究趋势。探讨在哪些方面能够取得胜利…

基于CTF探讨Web漏洞的利用与防范

写在前面 Copyright © [2023] [Myon⁶]. All rights reserved. 基于自己之前在CTF中Web方向的学习&#xff0c;总结出与Web相关的漏洞利用方法&#xff0c;主要包括&#xff1a;密码爆破、文件上传、SQL注入、PHP伪协议、反序列化漏洞、命令执行漏洞、文件包含漏洞、Vim…

数字孪生开发技术分析

数字孪生的开发涉及多个技术领域&#xff0c;包括计算机科学、数据科学、人工智能和工程等。以下是数字孪生开发中常用的一些关键技术&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.建模和仿真&am…

centos(linux)安装jenkins

官网&#xff1a;https://pkg.jenkins.io/redhat/ 安装官网进行操作&#xff1a; sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.reposudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io-2023.key若出现如下错误&#xff1a; …

智能优化算法应用:基于人工水母算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工水母算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工水母算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工水母算法4.实验参数设定5.算法结果6.…

Axure

目录 一. 交互 1.2 交互事件 二. 情形 2.1 应用场景 三. 案例 3.1 ERP登录 3.2 ERP页面跳转 一. 交互 交互事件是指在用户界面中发生某些操作或行为时&#xff0c;触发相应的响应或动作。在设计网页、应用程序或其他用户界面时&#xff0c;交互事件通常用于实现交互式功…

R语言【cli】——通过cli_abort用 cli 格式的内容显示错误、警告或信息,内部调用cli_bullets和inline-makeup

cli_abort(message,...,call .envir,.envir parent.frame(),.frame .envir ) 我先从那些不需要下大力气理解的参数入手&#xff1a; 参数【.envir】&#xff1a;进行万能表达式编译的环境。 参数【.frame】&#xff1a;抛出上下文。默认用于 .trace_bottom&#xff0c;当 .…

WordCloud—— 词云

【说明】文章内容来自《机器学习入门——基于sklearn》&#xff0c;用于学习记录。若有争议联系删除。 wordcloud 是python的第三方库&#xff0c;称为词云&#xff0c;也成文字云&#xff0c;可以根据文本中的词频以直观和艺术化的形式展示文本中词语的重要性。 依赖于pillow …

Instruct-NeRF2NeRF:通过用户指令编辑 NeRF 三维场景

Haque A, Tancik M, Efros A A, et al. Instruct-nerf2nerf: Editing 3d scenes with instructions[J]. arXiv preprint arXiv:2303.12789, 2023. Instruct-NeRF2NeRF 是 ICCV 2023 Oral 论文&#xff0c;首次将图像编辑任务从二维提升到三维。 Instruct-NeRF2NeRF 所做的任务…

b站高可用架构 笔记

b站高可用架构 关键点&#xff1a;主机房&#xff0c;多活和多活机房 参考文章&#xff1a;bilibili技术总监毛剑&#xff1a;B站高可用架构实践 1. 前端和数据中心负载均衡 前端负载均衡(动态CDN):最近节点、带宽策略、可用服务容量 数据中心负载均衡:均衡流量、识别异常节…

微软近日推出了Phi-2,这是一款小型语言模型,但其性能却十分强大

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

数据的个人视角:数据可视化的意义

当谈论到数据可视化对个人用户的实用价值时&#xff0c;很多人可能会想到它仅适用于企业或专业领域。然而&#xff0c;数据可视化对个人用户同样具有重要的实用价值。本文将从可视化从业者的角度出发&#xff0c;简单说说数据可视化对个人用户的实用价值。 首先&#xff0c;数…

【大数据存储与处理】第四次作业

一. 简答题&#xff08;共8题&#xff09; 1. (简答题)此题为mongodb操作题&#xff0c;使用在线平台或分享的虚拟机平台软件&#xff0c;写出命令&#xff0c;并把结果截图一起提交。对testdb数据库items集合进行聚合分组&#xff0c;然后在统计卖出的平均数量&#xff08;“…

云存储在 AIOps、数字人以及训练推理场景的最佳实践

云布道师 在以 AIGC 大模型为代表的技术新浪潮中&#xff0c;存储作为数据基础设施&#xff0c;将在数据采集、训练与推理、应用部署、内容审核与协同等多个关键环节发挥重要作用&#xff0c;助力 AI 创新加速。据 IDC 调研显示&#xff0c;67% 的中国企业已经开始探索 AIGC 在…

【PIE-Engine 数据资源】全球2.5分分辨率累积降水量数据集

文章目录 一、 简介二、描述三、波段四、示例代码参考资料 一、 简介 数据名称全球2.5分分辨率累积降水量数据集时间范围1961年- 2018年空间范围全球数据来源worldclim代码片段var images pie.lmageCollection(WORLDCLIME/GLOBAL_PREC_MONTH") 二、描述 全球2.5分分率果…

Linux笔记---用户和权限管理基本命令介绍

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux学习 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 ​编辑 前言&#xff1a; 命令&#xff1a; whoami&#xff1a; passwd&#xff1a; useradd&#xff1a; userdel&#xff1a; chm…

直升机产权共享,让飞行成为触手可及的梦想!

你曾想过能开直升机&#xff1f;甚至想拥有一架直升机&#xff1f;那种飞跃人生的心境&#xff0c;翱翔蓝天白云。可面临居多疑问&#xff0c;比如&#xff1a;学开直升机需要怎样的条件&#xff08;年龄、学历、费用、学习内容及周期等&#xff09;?到哪里学/买直升机比较安全…

【C语言】自定义类型之联合和枚举

目录 1. 前言2. 联合体2.1 联合体类型的声明2.2 联合体的特点2.3 相同成员的结构体和联合体对比2.4 联合体大小的计算2.4 判断当前机器的大小端 3. 枚举3.1 枚举类型的声明3.2 枚举类型的优点3.3 枚举类型的使用 1. 前言 在之前的博客中介绍了自定义类型中的结构体&#xff0c;…

利用Spark构建房价分析与推荐系统:基于58同城数据的大数据实践

利用Spark构建房价分析与推荐系统&#xff1a;基于58同城数据的大数据实践 基于Spark的房价数据分析预测推荐系统引言技术栈功能概述项目实现1. 数据爬取与处理2. 大数据分析与可视化3. 房价预测模型4. 协同过滤推荐系统5. Web应用开发6. 数据管理与用户管理 总结与展望 基于Sp…