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

你好,我是程序员雪球。

 

今天我们了解代理模式的原理、静态代理和动态代理的区别、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.mzph.cn/news/818521.shtml

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

相关文章

手把手带你搞懂电压跌落测试DIP

针对很多入门小白不懂元器件&#xff0c;一些老工程师上班很多年有的也不懂得总结知识点&#xff0c;以及想学习不知道怎么系统学习的这一类人群&#xff0c;前方知识点来袭&#xff0c;请君放心食用~ 一&#xff0c;项目背景介绍 最近做项目过程中&#xff0c;客户要求要做电…

wps使用Latex编辑公式没有Latex formula

wps使用Latex编辑公式没有Latex formula 1. 下载CTEX2. 下载LaTeXEE3. 配置Miktex4. 配置latexee5. 用管理员权限运行latexeqedit.exe6. wps插入latex公式 1. 下载CTEX 下载CTEX网址&#xff0c;我下载的下图这个&#xff0c;下载完了之后运行exe文件安装ctex。 2. 下载LaTe…

【Entity Framework】你要知道EF中功能序列与值转换

【Entity Framework】你要知道EF中功能序列与值转换 文章目录 【Entity Framework】你要知道EF中功能序列与值转换一、序列1.1 基本用法1.2 配置序列设置 二、值转换2.1 配置值转换器2.2 批量配置值转换器2.3 预定义的转换2.4 ValueConverter类2.5 内置转换器 三、应用3.1 简单…

Java中的TCP通信

TCP通信 TCP通信Socket客户端ServerSocket服务端 例子&#xff1a;一发一收例子&#xff1a;多发多收异常捕获 例子&#xff1a;服务器与多个客户端同时通信多客户端通信架构服务端代码ServerReaderThread 服务端读数据线程 TCP通信 特点&#xff1a;面向连接、可靠通信 通信双…

动态数据源实现分表走shardingsphere,不分表走其他

shardingsphere从4.1.1升级到5.2.1但是还没有完结&#xff0c;因为在执行存储过程的时候&#xff0c;系统提示错误如下。shardingsphere是不支持存储过程呢&#xff0c;但项目中不能避免使用存储过程&#xff0c;因为有大量的数据需要初始化&#xff0c;这种情况该如何应对&…

AI绘梦师新项目歪门邪道2.0游戏玩法,仅需拷贝,一键生成,单日盈利500

我们今天要介绍的项目是“AI绘梦师新项目歪门邪道2.0游戏玩法”。这个项目的核心是利用AI技术帮助企业将用户的梦境转化为美术作品。操作起来非常简单&#xff0c;只需复制用户描述的梦境内容&#xff0c;然后将其输入到AI绘画软件中&#xff0c;软件就能自动生成相应的画作。 …

APP开发突增20倍!安卓和鸿蒙你站哪边?

随着科技的快速发展&#xff0c;智能设备已经成为我们生活中不可或缺的一部分。 根据不少业内人士爆料&#xff0c;今年9月华为将发布mate70系列&#xff0c;而同时华为自己也官宣了"鸿蒙星河版"&#xff0c;也就是原生鸿蒙系统&#xff0c;将于今年4季度商用。这很…

顶顶通呼叫中心中间件-SIP分机安全(mod_cti基于FreeSWITCH)

介绍 运行在公网的FreeSWITCH服务器&#xff0c;每天都会接收到很多恶意的呼叫请求和注册请求&#xff0c;尝试盗打电话。合理的配置可以防止电话给倒打&#xff0c;但是每天大量的攻击&#xff0c;会让FS产生很多日志&#xff0c;降低FreeSWITCH的处理能力&#xff0c;cti模块…

Python实现时间序列ARIMA模型(附带超详细理论知识和完整代码实现)

文章目录 0 结果1 介绍2 建模2.1 预备知识2.1.1 ADF检验结果&#xff08;单位根检验统计量&#xff09;2.1.2 差分序列的白噪声检验&#xff08;这里使用Ljung-Box检验&#xff09;2.1.3 ARIMA模型&#xff08;差分整合移动平均自回归模型&#xff09;的三个参数:p&#xff0c;…

《系统分析与设计》实验-----需求规格说明书 哈尔滨理工大学

文章目录 需求规格说明书1&#xff0e;引言1.1编写目的1.2项目背景1.3定义1.4参考资料 2&#xff0e;任务概述2.1目标2.2运行环境2.3条件与限制 3&#xff0e;数据描述3.1静态数据3.2动态数据3.3数据库介绍3.4数据词典3.5数据采集 4&#xff0e;功能需求4.1功能划分4.2功能描述…

(一)C++自制植物大战僵尸集成开发环境安装

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/uzrnw 1、下载Visual Studio集成开发环境 首先在微软官网下载Visual Studio 2022 Community版本。Community版本是免费的&#xff0c;并且满足个人开发的各种需求。Visual Studio 2022 下载链接&#xff1a;微软官网。选…

springboot+vue全栈开发【2.前端准备工作篇】

目录 前言准备工作Vue框架介绍MVVM模式 快速入门导入vue在vscode创建一个页面 前言 hi&#xff0c;这个系列是我自学开发的笔记&#xff0c;适合具有一定编程基础&#xff08;html、css那些基础知识要会&#xff01;&#xff09;的同学&#xff0c;有问题及时指正&#xff01;…

在Windows上配置VS Code GO语言开发环境

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【代码随想录】【动态规划】完全背包:零钱兑换,组合总和

零钱兑换 零钱作为物品 &#xff0c;零钱的面额作为物品的重量 def change(self, amount, coins):""":type amount: int:type coins: List[int]:rtype: int"""dp [0]*(amount 1)dp[0] 1# 遍历物品for i in range(len(coins)):# 遍历背包for …

室内设计师怎么获取合适的3D模型?

在室内设计中&#xff0c;3D模型的使用已经变得越来越普遍。它们可以帮助设计师更好地展示他们的设计想法&#xff0c;同时也能帮助客户更好地理解他们所期待的装修效果。然而&#xff0c;如何获取合适的3D模型却是许多设计师和客户面临的挑战。那么室内设计师怎么获取合适的3D…

watchdog,监控文件变化的强大的python库

大家好&#xff0c;今天为大家分享一个无敌的 Python 库 - watchdog。 Github地址&#xff1a;github.com/gorakhargos… 在软件开发和系统管理领域&#xff0c;经常需要监控文件和目录的变化&#xff0c;以便在文件被创建、修改或删除时触发相应的操作。Python Watchdog是一…

有图片转成PDF文件格式的方法吗?分享图片转成PDF文件的方法

将图片转换为PDF文件是一个相对简单的过程&#xff0c;但也需要一定的步骤和注意事项。下面&#xff0c;我将详细介绍如何将图片转换为PDF文件&#xff0c;包括所需的工具、步骤以及可能遇到的问题和解决方案。 首先&#xff0c;我们需要一个能够将图片转换为PDF文件的工具。市…

【Booksim】Booksim2.0模拟器集成新拓扑

Incorporating a new topology in Booksim 1. 新拓扑结构2. 需要添加的文件3. 修改步骤 3.1 添加testnet.hpp3.2 添加testnet.cpp3.3 将testnet集成到network.cpp中3.4 创建配置文件testnetconfig3.5 在main.cpp和global.hpp中加入gP_testnet和gA_testnet变量3.6 make进行编译 …

尚小标-智能AI商标注册交易平台【24小时您口袋里的商标管家】

随着全球经济一体化进程的推进和科技的飞速发展&#xff0c;知识产权已经成为企业高质量发展的重要竞争关键因素&#xff0c;众多企业发展的核心竞争力。通过加强知识产权保护&#xff0c;企业可以更好地保护自身品牌形象和市场份额&#xff0c;从而提高国内外市场竞争力&#…

C语言洛谷题目分享(9)奇怪的电梯

目录 1.前言 2.题目&#xff1a;奇怪的电梯 1.题目描述 2.输入格式 3.输出格式 4.输入输出样例 5.说明 6.题解 3.小结 1.前言 哈喽大家好啊&#xff0c;前一段时间小编去备战蓝桥杯所以博客的更新就暂停了几天&#xff0c;今天继续为大家带来题解分享&#xff0c;希望大…