10、【代理模式】通过引入一个代理对象来控制对原始对象的访问的方式。

news2024/11/28 16:45:25

你好,我是程序员雪球。

 

今天我们了解代理模式的原理、静态代理和动态代理的区别、Spring AOP 和动态代理的关系、代理模式的使用场景,以及用 Java 实现一个动态代理示例

 684f0c326cc94a1d9960930ae42d5419.png

 

一、代理模式的原理

 

代理模式是一种设计模式,它提供了一种通过引入一个代理对象来控制对原始对象的访问的方式。代理对象在客户端和原始对象之间充当中间人,它可以在调用原始对象的方法之前或之后执行额外的操作,如日志记录、缓存、权限检查等。

 

在代理模式中,有三个主要角色:

 

1. 抽象主题(Subject):定义了原始对象和代理对象的公共接口,包含了原始对象的所有方法。

2. 具体主题(ConcreteSubject):实现了抽象主题接口,是实际的业务逻辑对象。

3. 代理(Proxy):实现了抽象主题接口,它持有一个具体主题对象的引用,并在调用具体主题的方法时可以添加额外的逻辑。

 

代理对象通常通过组合或继承的方式来实现对原始对象的包装。在调用代理对象的方法时,它会将请求转发给原始对象,并可以在调用前后执行自定义的逻辑。

 

二、静态代理和动态代理的区别

 

静态代理是在编译时创建的代理类,它通过继承原始对象的类或实现其接口,并在其中重写需要代理的方法来实现。静态代理在运行时会生成一个新的类,因此它的性能可能会受到一定的影响。

 

动态代理是在运行时动态创建的代理类,它通过使用反射机制在运行时生成代理对象的字节码,并将其加载到 JVM 中。动态代理通常使用 Java 的反射 API 和动态字节码生成技术来实现,如 Java 的 Proxy 类或 CGLIB 库。动态代理的优点是不需要在编译时生成代理类,因此可以更加灵活地处理各种代理需求。

 

三、Spring AOP 和动态代理的关系

 

Spring AOP(Aspect-Oriented Programming,面向方面编程)是 Spring 框架提供的一种强大的横切关注点技术,它基于动态代理实现。通过 Spring AOP,我们可以在不修改原始代码的情况下,将横切关注点(如日志记录、事务管理、权限检查等)编织到业务逻辑代码中。

 

Spring AOP 使用了动态代理来创建代理对象,并在调用原始对象的方法时自动执行横切逻辑。Spring AOP 支持两种类型的动态代理:基于 JDK 的动态代理和基于 CGLIB 的动态代理。基于 JDK 的动态代理要求被代理的对象必须实现至少一个接口,而基于 CGLIB 的动态代理则不需要接口。

 

在 Spring AOP 中,我们可以通过配置 XML 文件或使用注解来定义切入点(Pointcut)和横切逻辑(Advice),Spring 会在运行时根据切入点和横切逻辑自动创建代理对象,并将其注入到应用的上下文中。

 

四、代理模式的使用场景

 

代理模式在以下场景中非常有用:

 

1. 远程调用(RPC):在分布式系统中,代理对象可以作为远程服务的本地代表,将远程方法调用转换为本地调用,并处理网络通信和序列化等细节。

2. 缓存:通过使用代理对象,可以在调用原始对象的方法之前或之后检查缓存中是否已经存在结果,并返回缓存中的结果,以提高系统性能。

3. 权限检查:代理对象可以在调用原始对象的方法之前进行权限检查,只有具备足够权限的用户才能访问受保护的资源。

4. 日志记录:通过代理对象,可以在调用原始对象的方法之前或之后记录日志信息,以便跟踪和审计系统的操作。

5. 事务管理:代理对象可以在调用原始对象的方法之前开始事务,在方法成功执行后提交事务,或者在发生异常时回滚事务,以保证数据的一致性。

 

五、用 Java 实现一个动态代理示例

 

以下是一个简单的 Java 动态代理示例,使用了 JDK 的动态代理机制来创建一个代理对象,它会在调用原始对象的方法前后打印日志信息:

 

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

 

public class DynamicProxyExample {

 

    public static void main(String[] args) {

        // 创建一个原始对象

        HelloWorldImpl helloWorldImpl = new HelloWorldImpl();

 

        // 创建一个动态代理对象

        HelloWorldProxy helloWorldProxy = new HelloWorldProxy(helloWorldImpl);

 

        // 使用代理对象执行方法

        helloWorldProxy.sayHello();

    }

 

    // 原始对象的接口

    interface HelloWorld {

        void sayHello();

    }

 

    // 原始对象的实现类

    static class HelloWorldImpl implements HelloWorld {

        @Override

        public void sayHello() {

            System.out.println("Hello, World!");

        }

    }

 

    // 动态代理类

    static class HelloWorldProxy implements InvocationHandler {

        private HelloWorld helloWorld;

 

        public HelloWorldProxy(HelloWorld helloWorld) {

            this.helloWorld = helloWorld;

        }

 

        @Override

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            // 在调用方法之前打印日志信息

            System.out.println("Before method invocation: " + method.getName());

 

            // 调用原始对象的方法

            Object result = method.invoke(helloWorld, args);

 

            // 在调用方法之后打印日志信息

            System.out.println("After method invocation: " + method.getName());

 

            return result;

        }

    }

 

    // 使用 JDK 的动态代理机制创建代理对象

    public static Object createProxy(Object target, Class<?>[] interfaces) {

        return Proxy.newProxyInstance(

                target.getClass().getClassLoader(),

                interfaces,

                new HelloWorldProxy((HelloWorld) target)

        );

    }

}

 

 

在上述示例中,我们定义了一个原始对象  HelloWorldImpl ,它实现了  HelloWorld  接口。然后,我们创建了一个  HelloWorldProxy  类,它实现了  InvocationHandler  接口,用于处理代理对象的方法调用。在  invoke()  方法中,我们可以在调用原始对象的方法前后执行自定义的逻辑,如打印日志信息。

 

在  main()  方法中,我们创建了一个原始对象  helloWorldImpl ,并使用  createProxy()  方法创建了一个代理对象  helloWorldProxy 。最后,我们使用代理对象执行  sayHello()  方法,并观察控制台输出的日志信息。

 

请注意,使用动态代理需要导入  java.lang.reflect.Proxy  类。

 

总结

我们来总结一下今天学习的内容:

一、代理模式的原理:

代理模式是一种设计模式,它提供了一种通过引入一个代理对象来控制对原始对象的访问的方式。

二、静态代理与动态代理的区别:

静态代理是在编译时创建的代理类,它通过继承原始对象的类或实现其接口,并在其中重写需要代理的方法来实现。

动态代理是在运行时动态创建的代理类,它通过使用反射机制在运行时生成代理对象的字节码,并将其加载到 JVM 中。

三、使用场景

1、远程调用;

2、缓存;

3、记录日志;

4、事务管理;

5、权限检查;

 

希望这个示例能帮助你理解代理模式的原理和使用场景。如果你有任何其他问题,请随时提问。

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

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

相关文章

最新AI一键生成漫画推文爆款视频,10分钟1条原创视频,1条视频最高2000+?

最近&#xff0c;有些朋友一直在询问关于AI漫画推文的方法&#xff0c;虽然我原本对此并不特别感兴趣&#xff0c;但在他们的多次催促下… 今天&#xff0c;我将详细解析这个玩法&#xff01;、 项目 地 址 &#xff1a; laoa1.cn/1671.html 关于项目的收益&#xff0c;我…

麒麟信安LTF框架上线openEuler社区

麒麟信安LTF框架介绍 LTF&#xff08;Linux Test Framework&#xff09;是麒麟信安自动化组开发的一款面向Linux操作系统测试的自动化测试框架&#xff0c;目前已在openEuler社区开源。LTF工具积极投入国内各评测项目和日常版本测试任务中&#xff0c;汲取了在Linux自动化测试…

一篇文章带你了解Python常用自动化测试框架——Pytest!

在之前的文章里我们已经学习了Python自带测试框架UnitTest&#xff0c;但是UnitTest具有一定的局限性 这篇文章里我们来学习第三方框架Pytest&#xff0c;它在保留了UnitTest框架语法的基础上有着更多的优化处理 下面我们将从以下角度来介绍Pytest&#xff1a; Pytest基本介…

Unity之Unity面试题(四)

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之Unity面试题&#xff08;四&#xff09; TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取…

多轴机械臂/正逆解/轨迹规划/机器人运动学/Matlab/DH法 学习记录02——机械臂几何法与DH表示法

系列文章目录 本科毕设正在做多轴机械臂相关的内容&#xff0c;这里是一个学习机械臂运动学课程的相关记录。 如有任何问题&#xff0c;可发邮件至layraliufoxmail.com问询。 1. 数学基础 2. 机械臂几何法与DH表示法 文章目录 系列文章目录一、手臂几何法1.机械手臂2.机械手臂…

盘点数据领域1亿美金以上的收购记录

最近&#xff0c;Salesforce对数据复制巨头Informatica发出了收购邀约&#xff0c;金额预计110亿美金。 Salesforce前脚刚157亿美金买入Tableau&#xff0c;这下又想把Informatic买下&#xff0c;太豪横了。我们一起盘点数据领域还有哪些土豪收购记录&#xff1a; 数据领域&…

Qt中连接mysql

1、安装mysql&#xff0c;workbench&#xff0c;为mysql添加环境变量 2、安装Qt带src&#xff0c;然后到如下目录&#xff0c;找到mysql.pro(建议做个副本先) http://D:\Qt\Qt5.13.2\5.13.2\Src\qtbase\src\plugins\sqldrivers\mysql mysql.pro 注意路径的 \ / 和双引号的使…

【javaWeb 第七篇】后端-Spring

Spring SpringspringBoot请求简单参数实体参数数组集合参数日期参数JSON参数路径参数 响应数据分层解耦三层架构解耦操作Bean的声明Bean组件扫描问题DI详解 Spring 详细介绍结合官网查看&#xff1a;https://spring.io/why-spring Spring发展到今天已经形成一种开发生态圈&…

KNIME 国际化支持投票

你的投票也许能让 KNIME 中文化快一点点。 i18n 是个很搞笑的单词&#xff0c;它是英文 internationalization 国际化的缩写。18 指的是首字母i和末字母n中间有18个字母。另外还有什么 K8s 也是一样&#xff0c;中间省去了8个字母 ... 真是懒的可以。指北君还想起一个类似的笑话…

微信小程序全局配置

全局配置文件及常用的配置项 小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下&#xff1a; ① pages 记录当前小程序所有页面的存放路径 ② window 全局设置小程序窗口的外观 ③ tabBar 设置小程序底部的 tabBar 效果 ④ style 是否启用新版的组件样…

vue3+ts中判断输入的值是不是经纬度格式

vue3ts中判断输入的值是不是经纬度格式 vue代码&#xff1a; <template #bdjhwz"{ record }"><a-row :gutter"8" v-show"!record.editable"><a-col :span"12"><a-input placeholder"经度" v-model:v…

CookieSession

目录 什么是会话 一.Cookie 1.Cookie介绍 2.Cookie的作用 3.Cookie的基本使用 4.Cookie生命周期 5.Cookie有效路径 6.注意事项 二.Session 1.Session基本原理 2 Session的作用 3.Session的基本使用 4.Session底层实现机制 5.Session生命周期 什么是会话 Cookie和S…

C++从入门到精通——类的6个默认成员函数之赋值运算符重载

赋值运算符重载 前言一、运算符重载定义实例注意要点 二、赋值运算符重载赋值运算符重载格式赋值运算符重载要点重载要点传值返回和传址返回要点 三、前置和后置重载 前言 类的6个默认成员函数&#xff1a;如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么…

Cloudflare Workers 付费文档

定价 默认情况下&#xff0c;用户可以访问Workers免费计划。Workers免费计划包括对Workers、Pages Functions和Workers KV的有限使用。了解更多关于免费计划限制的信息。 Workers付费计划包括Workers、Pages Functions、Workers KV和Durable Objects的使用&#xff0c;每个账…

移植speexdsp到OpenHarmony标准系统②

在linux上生成speexdsp的so动态链接库和.a静态链接库 make和make install后会生成speexdsp的.so动态链接库和.a静态链接库 make make install其中build/lib目录下&#xff1a; ├── libspeexdsp.a /*静态库*/ ├── libspeexdsp.la …

基于Springboot+Vue的Java项目-免税商品优选购物商城系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

MySQL 列数据跨表拷贝,一句SQL快速将表A每条记录的某些字段拷贝到表B每条记录的某些字段(A、B表通过ID对应)

文章目录 MySQL 列数据跨表拷贝&#xff0c;一句SQL快速将表A每条记录的某些字段拷贝到表B每条记录的某些字段&#xff08;A、B表通过ID对应&#xff09;背景定义表填充测试数据跨表一 一对应拷贝列数据SQL参考资料 MySQL 列数据跨表拷贝&#xff0c;一句SQL快速将表A每条记录的…

创建影子用户

文章目录 1.认识影子用户2.创建隐藏账户并加入管理员组3.修改注册表3.删除用户4.添加管理员权限 1.认识影子用户 影子用户通常指的是那些在系统用户列表中不可见&#xff0c;但在某些情况下可以进行操作的用户。在内网渗透过程中&#xff0c;当我们拿到shell时&#xff0c;肯定…

某小学AK,SK泄露导致横向到云主机控制台

目录 前言 免责声明 分享声明 个人介绍 某小学AK&#xff0c;SK泄露导致横向到云主机控制台 一、 资产证明 资产证明(1) 资产证明(2) 二、漏洞利用过程 三、漏洞危害 四、修复建议 五、预防措施 前言 免责声明 以下漏洞均已经上报漏洞平台。请勿利用文章内的相关…

Android Jetpack学习系列——Room

关于Room&#xff1a; Room是Android Jetpack组件之一&#xff0c;旨在为Android应用程序提供一种简单、强大且易于使用的本地数据库访问解决方案。 关键特性&#xff1a; 1.基于SQLite封装&#xff1a;Room是基于SQLite数据库引擎构建的&#xff0c;提供了面向对象的API来与…