Java代理模式详细

Java代理模式详细

一、引言

代理模式(Proxy Pattern)是一种常用的设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在Java中,代理模式可以分为静态代理和动态代理两种。本文将详细介绍代理模式的概念、实现方式以及应用场景。

二、代理模式的概念

代理模式是一种对象结构型模式,它给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。代理模式涉及三个角色:

  1. 抽象角色(Subject):声明了真实对象和代理对象的共同接口。
  2. 真实角色(RealSubject):代理对象所代表的真实对象,是最终要引用的对象。
  3. 代理角色(Proxy):代理对象,内部含有对真实对象的引用,并且可以控制对真实对象的访问,同时可以在客户端和目标对象之间起到中介的作用。

三、静态代理

静态代理是指在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

实现步骤

  1. 创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法。
  2. 创建一个代理类,同时使其也实现这个接口。
  3. 在代理类中持有一个被代理对象的引用,并在代理类中的方法中调用该对象的方法。

示例代码

// 接口
public interface Subject {void request();
}// 真实角色
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("执行真实对象的方法!");}
}// 代理角色
public class ProxySubject implements Subject {private RealSubject realSubject;@Overridepublic void request() {if (realSubject == null) {realSubject = new RealSubject();}preRequest();realSubject.request(); // 调用真实对象的方法postRequest();}// 在请求之前执行private void preRequest() {System.out.println("调用真实对象之前的服务。");}// 在请求之后执行private void postRequest() {System.out.println("调用真实对象之后的服务。");}
}// 客户端
public class Client {public static void main(String[] args) {Subject subject = new ProxySubject();subject.request(); // 客户端通过代理对象访问真实对象的方法}
}

四、动态代理

动态代理是指在程序运行时动态地创建代理对象,并实现对真实对象的代理访问。Java中的动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。

实现步骤

  1. 创建一个实现接口InvocationHandler的类,它必须实现invoke方法,以供代理实例的调用处理程序使用。
  2. 创建被代理的类以及接口。
  3. 通过ProxynewProxyInstance静态方法创建代理对象,该方法需要接收三个参数:类加载器、一组接口以及调用处理器实例。

示例代码

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 真实角色
public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("执行真实对象的方法!");}
}// 调用处理器
public class DynamicProxy implements InvocationHandler {private Object subject;public DynamicProxy(Object subject) {this.subject = subject;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {preRequest();Object result = method.invoke(subject, args);postRequest();return result;}private void preRequest() {System.out.println("调用真实对象之前的服务。");}private void postRequest() {System.out.println("调用真实对象之后的服务。");}
}// 客户端
public class Client {public static void main(String[] args) {RealSubject realSubject = new RealSubject();Subject proxy = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new DynamicProxy(realSubject));proxy.request(); // 客户端通过代理对象访问真实对象的方法}
}

五、代理模式的应用场景

  1. 远程代理:为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。
  2. 虚拟代理:根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象。
  3. 保护代理:控制对原始对象的访问,用于对象应该有不同的访问权限的时候。
  4. 智能指引:取代了简单的指针,它在访问对象时执行一些附加操作,比如:对指向实际对象的引用计数、第一次引用一个持久对象时,将它装入内存等。

六、总结

代理模式是一种非常有用的设计模式,它可以在不修改原始类代码的情况下,通过引入代理类来给原始类附加额外的功能或控制。在Java中,静态代理和动态代理是实现代理模式的两种主要方式,它们各自适用于不同的场景。理解并掌握代理模式对于提高代码的可维护性和可扩展性具有重要意义。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[极客大挑战 2019]PHP1

打开靶机 提示有备份,可以用工具扫描,我还没有配置好环境,搜了一下其他师傅的:备份的地址在这: /www.zip 下载后得到这几个文件: index.php就是上面打开的网页,其中有一段php代码:…

谷粒商城实战笔记-72-商品服务-API-属性分组-获取分类属性分组

文章目录 一,后端接口开发Controller层修改接口接口测试 二,前端开发 这一节的内容是开发获取分类属性分组的接口。 一,后端接口开发 Controller层修改接口 修改AttrGroupController接口。 RequestMapping("/list/{catelogId}")p…

ROS getting started

文章目录 前言一、认识ROS提供的命令行工具nodestopicsservicesparametersactionsrqt_console, rqt_graph批量启动多个节点recorde and playc基础pub-sub 1.5 ROS2和fastdds1 改变订阅模式2 xml配置3 指定xml位置4 talker/listener通过发现服务器发送topic5 ros2 检视6 远程fas…

Redis zset 共享对象

前言 本文介绍 Redis 中 skiplist 编码的 zset 对象是如何共享对象的。 skiplist 编码的 zset 对象为了同时支持高效的点查询和范围查询,内部使用了跳表和哈希表。倘若将每个插入的元素都拷贝两份,分别插入跳表和哈希表,将浪费大量的内存&a…

Unity 骨骼动画(Skinned Mesh Renderer): 角色动画的高级渲染

在Unity中,骨骼动画(Skinned Mesh Renderer)是一种用于高级角色动画渲染的组件。它允许开发者将复杂的3D模型和动画应用到游戏角色上,实现逼真的视觉效果。本文将探讨Skinned Mesh Renderer的基本概念、使用方法以及如何优化性能。 Skinned Mesh Render…

Docker容器的数据管理

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 我们在使用Docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份&#x…

信创终端操作系统上vmware的命令行操作

原文链接:信创终端操作系统上vmware的命令行操作 Hello,大家好啊!今天给大家带来一篇关于在信创终端操作系统上使用命令行操作VMware的文章。通过命令行管理VMware虚拟机可以提高效率,特别是在需要批量操作或自动化管理时。本文将…

Python脚本批量将md文件转化成pdf

自己学编程时做了很多笔记,如今累积起来已经有几十个了,有很多图片链,怕哪天图床垮了图片就找不到了,于是就想把当时的 md 文件都转成 pdf 。 看了点文章,就开始实践: 1.下载 pandoc 和 CTex 2.ChatGpt …

VS2022创建C C++ GTEST工程

原因 需要对带代码进行单元测试,选择在Visual studio 中使用GTEST 框架。 实施 创建一个常规的控制台可执行程序。然后使用NUGET安装包 安装GTEST 头文件和动态库,同时安装GTEST ADAPTER。 安装可能提示找不到包源,此时需要根据提示配置一…

如何使用API快速打造健康医疗系统?

在数字医疗市场,数据是人们经常谈及的一个话题。当前,消费者医疗和健康应用收集的数据越来越多,电子健康记录的实施也创造出了大量有关病人的电子信息。 API接口在智慧医院跨网、跨机构之间的业务协同和数据共享交换中得到数据共享。支撑了医…

环境搭建-Docker搭建MySQL

Docker搭建MySQL 一、前言二、Docker安装MySQL5.7安装三、建立远程连接四、Docker安装MySQL8.0 一、前言 本文使用的Docker使用Windows搭建,Linux版本的搭建方式一样。 Windows系统搭建Docker 二、Docker安装MySQL5.7安装 拉取MySQL指定版本的镜像 docker pull …

Redis从入门到超神-(十二)Redis监听Key的过期事件

前言 试想一个业务场景,订单超过30分钟未支付需要做自动关单处理,修改订单状态,库存回退等,你怎么实现?方案一:可以使用定时任务扫表,通过支付状态和下单时间来判断是否支付过期。但是这样的方案是非常消耗…

2846. 边权重均等查询

Powered by:NEFU AB-IN Link 文章目录 2846. 边权重均等查询题意思路代码 2846. 边权重均等查询 题意 现有一棵由 n 个节点组成的无向树,节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] [ui, vi…

实战:在Spring Boot中使用线程池

在处理高并发请求时,直接创建和销毁线程会带来巨大的开销。线程池通过重用现有的线程来减少这种开销,提高应用的性能和响应速度。SpringBoot提供了便捷的方式来配置和使用线程池。 在SpringBoot中使用线程池,可以有效提高应用的并发处理能力…

MacOS DockerDesktop配置文件daemon.json的位置

如果因为通过可视化页面修改配置错误导致客户端启动不起来,可以去找对应的配置文件通过 vim 修改后重启客户端 cd ~/.docker/

C#使用Clipper2进行多边形合并、相交、相减、异或的示例

Clipper2库介绍 开源库介绍: Clipper2在Github上的地址:https://github.com/AngusJohnson/Clipper2 Clipper2库对简单和复杂多边形执行交集(Intersection)、并集(Union)、差分(Difference&…

protobuf编译之后找不到isStringEmpty方法

原因: 与mysql的jar包冲突了 解决办法&#xff1a; 在MySQL中排除proto-java <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.22</version><scope>runtime</scope>&l…

Webpack 从入门到精通

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Webpack 简介 二、Webpack 的核心概念 三、Webpack 的安装与配置 安装 Node.js 安装 Webpack 初始…

戴着苹果Vision Pro,如何吃花生米

6月底苹果Vision Pro国内开售&#xff0c;我早早到官网预订了一台。选择必要的配件&#xff0c;输入视力信息&#xff0c;定制符合自己视力的蔡司镜片。确实贵。把主要配件和镜片配齐&#xff0c;要3万6&#xff0c;比Pico、META的眼镜贵一个数量级。 Vision Pro出来后&#x…

C语言之.(结构体,枚举,共用体的应用)

C语言之.(结构体&#xff0c;枚举&#xff0c;共用体的应用) 结构体&#xff0c;套联合体&#xff0c;枚举的应用例子