深入理解代理模式(Proxy Pattern)及其实际应用

引言

在软件开发中,有时候我们需要在不改变现有代码的情况下添加一些功能,比如延迟初始化、访问控制、日志记录等。代理模式(Proxy Pattern)通过代理对象控制对原对象的访问,为现有代码添加了额外的功能。本篇文章将详细介绍代理模式的概念、应用场景、优缺点,并通过Java代码示例展示代理模式的实际应用。

1. 什么是代理模式?

代理模式是一种结构型设计模式,它提供一个代理对象控制对原对象的访问。代理模式可以在不修改原对象的情况下,向其添加一些功能,比如访问控制、延迟加载、日志记录等。

代理模式的结构

代理模式包含以下几个主要角色:

  • 抽象主题(Subject):定义代理类和真实主题类的公共接口。
  • 真实主题(RealSubject):实现抽象主题接口,定义真实对象。
  • 代理(Proxy):实现抽象主题接口,包含对真实主题对象的引用,并可以在调用真实主题对象前后添加额外功能。

2. 代理模式的代码示例

示例背景

假设我们有一个简单的业务服务类,它有一个方法需要在调用前后执行一些日志记录。我们可以使用代理模式来实现这一点。

抽象主题接口

首先,我们定义抽象主题接口:

// 抽象主题接口
interface BusinessService {
    void performTask();
}

真实主题类

然后,我们定义真实主题类:

// 真实主题类
class RealBusinessService implements BusinessService {
    @Override
    public void performTask() {
        System.out.println("Performing the main task...");
    }
}

代理类

接下来,我们定义代理类,在方法调用前后执行增强内容:

// 代理类
class BusinessServiceProxy implements BusinessService {
    private RealBusinessService realBusinessService;

    public BusinessServiceProxy(RealBusinessService realBusinessService) {
        this.realBusinessService = realBusinessService;
    }

    @Override
    public void performTask() {
        logBefore();
        realBusinessService.performTask();
        logAfter();
    }

    private void logBefore() {
        System.out.println("Log before method execution");
    }

    private void logAfter() {
        System.out.println("Log after method execution");
    }
}

客户端代码

最后,我们在客户端代码中使用代理模式:

public class ProxyPatternDemo {
    public static void main(String[] args) {
        RealBusinessService realBusinessService = new RealBusinessService();
        BusinessService businessService = new BusinessServiceProxy(realBusinessService);

        // 调用方法前后会执行增强内容
        businessService.performTask();
    }
}

输出

Log before method execution
Performing the main task...
Log after method execution

解释

在这个示例中,我们定义了一个业务服务接口 BusinessService 及其实现类 RealBusinessService,并通过代理类 BusinessServiceProxy 在方法调用前后添加了日志记录功能。代理类在调用真实业务服务对象的方法前后,分别调用了 logBeforelogAfter 方法,从而实现了在方法调用前后执行增强内容。

3. 代理模式在实际框架中的应用

代理模式在许多实际框架中都有广泛的应用。下面我们以Spring AOP(面向切面编程)为例,展示代理模式如何在实际应用中为现有代码添加额外功能。

案例分析:Spring AOP

Spring AOP通过代理对象为现有代码添加了日志记录、事务管理、权限控制等功能。Spring AOP可以在不修改现有代码的情况下,通过代理对象在方法调用前后添加额外的功能。

具体实现

下面是一个使用Spring AOP的示例:

1. 添加依赖

首先,在Maven的pom.xml文件中添加Spring AOP的依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.3.9</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.9</version>
</dependency>
2. 目标对象

定义业务服务类:

// 目标对象
public class MyService {
    public void performTask() {
        System.out.println("Performing task...");
    }
}
3. 切面类

定义切面类,在方法调用前后执行增强内容:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;

@Aspect
public class LoggingAspect {
    @Before("execution(* MyService.performTask(..))")
    public void logBefore() {
        System.out.println("Log before method execution");
    }

    @After("execution(* MyService.performTask(..))")
    public void logAfter() {
        System.out.println("Log after method execution");
    }
}
4. Spring 配置文件

定义Spring配置文件(aop-config.xml):

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="myService" class="MyService"/>
    <bean id="loggingAspect" class="LoggingAspect"/>

    <aop:config>
        <aop:aspect ref="loggingAspect">
            <aop:pointcut id="performTaskPointcut" expression="execution(* MyService.performTask(..))"/>
            <aop:before method="logBefore" pointcut-ref="performTaskPointcut"/>
            <aop:after method="logAfter" pointcut-ref="performTaskPointcut"/>
        </aop:aspect>
    </aop:config>
</beans>
5. 客户端代码

在客户端代码中使用Spring AOP:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringAOPDemo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("aop-config.xml");
        MyService myService = (MyService) context.getBean("myService");
        myService.performTask();
    }
}

输出

Log before method execution
Performing task...
Log after method execution

解释

在这个示例中,Spring AOP通过代理对象在方法调用前后添加了日志记录功能,实现了代理模式。在Spring AOP配置文件中,我们定义了切面(Aspect)和切入点(Pointcut),并指定在目标方法调用前后执行增强内容。

4. 代理模式的优缺点

优点

  • 控制对象访问:可以在访问对象时添加额外的功能,比如权限控制、延迟加载等。
  • 增强对象功能:可以在不修改现有代码的情况下,为对象添加新的功能。
  • 灵活性高:代理对象可以灵活地控制对真实对象的访问。

缺点

  • 增加复杂性:需要引入代理对象,增加了系统的复杂性。
  • 性能开销:代理对象会增加方法调用的开销,影响系统性能。

5. 总结

代理模式通过代理对象控制对原对象的访问,为现有代码添加了额外的功能。在业务服务的示例中,我们展示了如何通过代理类在方法调用前后执行增强内容,实现了日志记录功能。在Spring AOP中的应用展示了代理模式的实际效果,极大地增强了系统的功能和灵活性。

希望这篇文章对你理解代理模式有所帮助。如果觉得本文内容有价值,请点赞、收藏和关注我们,获取更多设计模式的精彩内容!

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

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

相关文章

Qt开发 | Qmake与CMake | Qt窗口基类 | VS Qt项目与QtCreator项目相互转化 | Qt架构 | Qt学习方法

文章目录 一、Qmake与CMake介绍1.Qmake2.CMake3.使用qmake还是cmake&#xff1f; 二、Qt3个窗口基类的区别三、vs qt与QtCreator项目相互转化方法1.QtCreator项目转VS Qt2.VS Qt项目转QtCreator项目 四、Qt架构介绍与学习方法详解 一、Qmake与CMake介绍 Qmake和CMake都是构建系…

vue启动时的错误

解决办法一&#xff1a;在vue.config.js中直接添加一行代码 lintOnSave:false 关闭该项目重新运行就可启动 解决办法二&#xff1a; 修改组件名称

机械装备制造行业MES,实时监控生产流程

装备制造行业MES&#xff0c;是专门为装备制造行业设计的生产信息化管理系统。旨在实时监控装备制造生产流程&#xff0c;实现全流程的精细化管理和监控&#xff0c;提高生产效率、降低生产成本、提升产品质量。 本文将详细介绍装备制造行业MES的概念、技术及应用&#xff0c;…

放大招了|十亿参数大模型LLMs运行功耗仅需13W,内存使用量减少90%!

矩阵乘法&#xff08;MatMul&#xff09;历来是大型语言模型&#xff08;LLMs&#xff09;总体计算成本的主导因素&#xff0c;尤其在模型向更大维度嵌入和上下文长度发展时&#xff0c;这一成本呈指数级增长。 近期有一篇刚刚发表的论文中提出的方法完全去除了矩阵乘法操作&am…

系统架构师考点--系统配置与性能评价

大家好。今天我们来总结一下系统配置与性能评价的考点内容&#xff0c;这一部分一般是出在上午场的选择题中&#xff0c;占1-2分左右。 一、性能指标 计算机 对计算机评价的主要性能指标有&#xff1a;时钟频率(主频)&#xff1b;运算速度&#xff1b;运算精度内存的存储容量…

现在纠结于到底是学stm32好还是Arduino好?

如果你就是要搞单片机&#xff0c;学STM32。 如果你要搞机器人、物联网、机器视觉、自动驾驶&#xff0c;就要学Arduino。 搞单片机&#xff0c;除了STM32之外&#xff0c;重点在于画好原理图和PCB。刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「stm32的…

HarmonyOS Next开发学习手册——内存管理(GC)

GC&#xff08;全称 Garbage Collection&#xff09;&#xff0c;即垃圾回收。在计算机领域&#xff0c;GC就是找到内存中的垃圾&#xff0c;释放和回收内存空间。当前主流编程语言实现的GC算法主要分为两大类&#xff1a;引用计数和对象追踪&#xff08;即Tracing GC&#xff…

【系统架构设计师】计算机组成与体系结构 ③ ( 层次化存储结构 | 寄存器 | 高速缓存 | 内存 | 外存 )

文章目录 一、层次化存储结构1、层次化存储结构2、层次化存储结构 - 示例说明3、程序员可操作的部分 计算机 采用 分级存储结构 , 主要目的是 为了 解决 容量 / 价格 / 速度 之间的矛盾 ; 一、层次化存储结构 1、层次化存储结构 计算机 存储器 按照存储速度 由快到慢 进行排序 …

算法入门:二分查找及其Java实现

在程序开发中&#xff0c;算法是解决问题的核心。本篇博客将详细讲解一种高效的查找算法——二分查找&#xff0c;并通过Java代码示例帮助你理解其实现和应用。 如果你觉得这篇文章对你有帮助&#xff0c;不要忘记点赞、收藏和关注我&#xff0c;这将是对我最大的支持和鼓励&am…

2、数据库模型图、er图

关系 user和administarators是多对一的关系 user和order是一对多的关系 shipped和order是多对一的关系 order和books是多对多的关系 leavewords和order是一对一的关系 stock和books是一对多的关系 Chens 数据库表示法——ER图 Crows Foot数据库表示法——数据库模型图 Navicat表…

%运算符

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法介绍 在python中&#xff0c;可以使用%运算符进行灵活多样的格式化处理&#xff0c;通用的语法格式为&#xff1a; &#xff08;格式模板&…

9.二维数组的遍历和存储

二维数组的遍历和存储 二维数组的遍历 二维数组a[3][4],可分解为三个一维数组,其数组名分别为: 这三个一维数组都有4个元素,例如:一维数组a[0]的 元素为a[0][0],a[0][1],a[0][2],a[0][3]。所以遍历二维数组无非就是先取出二维数组中得一维数组, 然后再从一维数组中取出每个元…

关于摄像头模组中滤光片的介绍

1、问题背景 红外截止滤光片&#xff08;IR CUT Filter&#xff09;是应用在摄像头模组中非常重要的一个器件&#xff0c;因人眼与 coms sensor 对光线各波长的响应不同&#xff0c; 人眼看不到红外光&#xff0c;但 sensor 能感应到&#xff08;如下图是某sensor在各波长下的…

Docker之jekins的安装

jekins官网地址&#xff1a;Jenkins Plugins &#xff08;https://plugins.jenkins.io/&#xff09; jekins 的docker 官方地址&#xff1a;https://hub.docker.com/r/jenkins/jenkins jekins 的docker 允许命令文档地址&#xff1a; docker/README.md at master jenkinsci…

40岁学习java是否需要报班学习?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;应该不需要。各种公开免费的…

CS-隐藏防朔源-数据转发-中间件反向代理-Apache

目录 1、代理机安装Apache: 2、中间件设置转发&#xff1a; 添加代理 3、重启Apache服务 4、CS监听器配置转发机IP 实战情况下还是要准备两台外网服务器. --还是做个中转 1、代理机安装Apache: apt-get install apache2 a2enmod proxy proxy_ajp proxy_balancer proxy_co…

用友 U8+ 控制金额、单价等字段权限设置

进入路径 系统服务——权限——数据权限控制设置 本功能是数据权限设置的前提&#xff0c;用户可以根据需要先在数据权限控制设置中选择需要进行权限控制的对象。 数据权限的控制分为记录级和字段级两个层次&#xff0c;对应系统中的两个页签"记录级"和"字段…

配置Nginx二级域名

一、环境 &#xff08;一&#xff09;配置 1.服务器 linux CentOS 2.反向代理 Nginx 3.开放端口 云服务器开放端口80和443 二、域名备案 &#xff08;一&#xff09;腾讯云 1.腾讯云域名备案流程 备注&#xff1a;一级域名备案后&#xff0c;二级域名可以不用再备案&a…

Construct公司 从 0 到 1 基于 Kitex+Istio 的微服务系统建设

本文根据 2024 年 5 月 25 日在上海举办的“云原生✖️AI 时代的微服务架构与技术实践”CloudWeGo 技术沙龙上海站活动中&#xff0c;Construct 服务端总监 Jason 的演讲《从 0 到 1 基于 Kitex Istio 的微服务系统建设》整理而来。 在微服务架构的浪潮中&#xff0c;企业面临…