代理模式与动态代理深入理解

news2025/7/19 11:12:54

一,代理模式的简单认识

1.参与者: 代理对象,被代理对象

代理对象相当于现实生活中的房产中介被代理对象
相当于 房东

2.目的:保护被代理对象

避免外界直接修改被代理对象,破坏掉被代理对象原本的功能。
将对被代理对象功能的增强放在代理对象中,
代理对象中存在一个对被代理对象的引用,在使用被代理对象之前或者之后,代理对象可以做一些额外的添油加醋方法。
(这符合开闭原则: 对修改关闭,对拓展开放
在这里插入图片描述

被代理对象 ProxyObjected.java

package src.com.liu.proxy;
//被代理对象(房东)
public class ProxyObjected {
    public void process(){
        System.out.println("我是被代理对象的方法 process");
    }
}

代理对象 ProxyObject.java

package src.com.liu.proxy;
//代理对象(中介)
public class ProxyObject {
    private ProxyObjected obj;
    ProxyObject(ProxyObjected obj){
        this.obj = obj;
    }
    public void process(){
        ProxyObjected obj = this.obj;

        System.out.println("====被代理对象的方法执行之前,执行添油加醋的动作");
        //执行被代理对象
        obj.process();
        System.out.println("====被代理对象的方法执行之后,执行一些添油加醋的动作");
    }
}

测试代码

package src.com.liu.proxy;

public class Test {
    public static void main(String[] args) {
            //创建被代理对象
            ProxyObjected obj = new ProxyObjected();
            //创建代理对象(把被代理对象当作参数传入)
            ProxyObject proxyObject = new ProxyObject(obj);
            //执行代理对象的方法(先执行添油加醋,再执行被代理对象的process,再执行添油加醋)
            proxyObject.process();
    }

}

在这里插入图片描述

二,动态代理

动态代理的意思是我们不直接生成我们的proxyObject,
而是提供 1.被代理对象和 2.增强方法(那些添油加醋方法)3.以及各自调用时机,然后在代码运行时自动帮我们生成一个proxyObject。
好处: 将代理对象方法和增强方法(添油加醋方法)解耦分离,使代码更具拓展型和可维护性。

这里只讲jdk动态代理

2.1 被代理对象 TestDao.java

package src.com.liu.proxy.dynamic.jdk;

public interface TestDao {
    public void save();
    public void modify();
    public void delete();
}

2.2 被代理对象实现类 TestDaoImpl.java

package src.com.liu.proxy.dynamic.jdk;

public class TestDaoImpl implements TestDao{
    @Override
    public void save() {
        System.out.println("保存");
    }

    @Override
    public void modify() {
        System.out.println("修改");
    }

    @Override
    public void delete() {
        System.out.println("删除");
    }
}

2.3 代理对象的增强方法 类 Enhancement.java

package src.com.liu.proxy.dynamic.jdk;
//代理对象的增强方法 类
public class Enhancement {
    public void check(){
        System.out.println("模拟权限控制");
    }
    public void except(){
        System.out.println("模拟异常处理");
    }
    public void log(){
        System.out.println("模拟日志记录");
    }
    public  void monitor(){
        System.out.println("性能监测");
    }
}

2.4 代理对象类 JDKDynamicProxy.java

package src.com.liu.proxy.dynamic.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//代理对象类
public class JDKDynamicProxy implements InvocationHandler
{
    private TestDao testDao;//被代理对象
    JDKDynamicProxy(TestDao dao){
        this.testDao= dao;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Enhancement enhancement = new Enhancement();
        enhancement.check();
        enhancement.except();

        //调用被代理对象方法
        Object obj = method.invoke(testDao,args);

        enhancement.log();
        enhancement.monitor();
        return  obj;
    }
}

2.5 JDKDynamicTest.java

package src.com.liu.proxy.dynamic.jdk;

import java.lang.reflect.Proxy;

public class JDKDynamicTest {
    public static void main(String[] args) {
        //创建被代理对象
        TestDao testDao = new TestDaoImpl();
        //创建代理对象,并将被代理对象注入到代理对象中
        JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(testDao);


        //得到一个类加载器
        ClassLoader classLoader = JDKDynamicProxy.class.getClassLoader();
        //得到被代理对象的所有接口
        Class[] clazz = testDao.getClass().getInterfaces();
        //生成代理对象
        TestDao testDaoAdvice = (TestDao) Proxy.newProxyInstance(classLoader,clazz,jdkDynamicProxy);

        //执行方法
        testDaoAdvice.save();
        System.out.println("====================");
        testDaoAdvice.modify();
        System.out.println("====================");
        testDaoAdvice.delete();
    }
}

2.6效果:
在这里插入图片描述

2.7 改变 Enhancement.java类中增强方法里的内容时,不改变现有代码运行
在这里插入图片描述
运行结果:
在这里插入图片描述
这实现了 代理对象里那些添油加醋增强方法 的结偶,
当这些增强方法需要修改时,不用动代理对象类里的代码

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

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

相关文章

KubeGems容器云平台体验

KubeGems容器云平台体验 KubeGems 是一款开源的企业级多租户容器云平台。围绕云原生社区,KubeGems 提供了多 Kubernetes 集群接入能力,并具备丰富的组件管理和资源成本分析功能,能够帮助企业快速的构建和打造一个本地化、功能强大且低成本的…

关于BigInteger和BigDecimal

BigInteger BigInteger类是用于解决整形类型(含基本数据类型及对应的包装类,)无法表示特别大的数字及运算的问题,即使是占用字节数最多的整形long,能表示的范围也是有限的.理论上,你可以使用BigInteger表示任意整数基于java8中BigInteger的构造方法. BigDecimal的构造方法2 …

Java代码审计基础——RMI原理和反序列化利用链

目录 (一)何为RMI (二)、 RMI的模式与交互过程 0x01 设计模式 0x02 交互过程 0x03 Stub和Skeleton (三)简单的 RMI Demo 1、Server 2、Registry 3、Client 补充——动态类加载机制 几个函数 (…

Java集合框架详解(四)——Map接口、HashMap类、LinkedHashMap类

一、Map接口 Map接口的特点: (1)映射键值对的形式(key和value); (2)Map集合中,key是不能重复的,value是可以重复的; (3)…

解决报错:fatal: Authentication failed for ‘https://github.com/*/*.git/‘

目录 问题 解决 步骤一、 步骤二、 步骤三、 ​步骤四、 ​步骤五、 步骤六、 问题 今天创建一个 github 新仓库,首次上传本地代码时,遇到了一个报错。但是,之前这样操作肯定是没有问题的,毕竟我可以保证用户名和密码都是…

复杂环境下多移动机器人路径规划研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

数据结构 | 顺序栈与链式队【栈与队列的交际舞】

数据结构之栈与队列🌳顺序栈🍃前言🔥栈的结构简介及概述🔥为什么要用顺序栈?🔥结构声明🍃接口算法实现🍞初始化栈🍞销毁栈🍞入栈🍞出栈&#x1f3…

磨金石教育|干货分享:剪辑技法之跳切(上)

有一种剪辑手法划分了传统剪辑与现代剪辑的界限,它就是“跳切”; 跳切,是“切”的一种。属于一种无技巧的剪辑手法。它打破常规状态镜头切换时所遵循的时空和动作连续性要求,以较大幅度的跳跃式镜头组接,突出某些必要内…

【kafka】三、kafka命令行操作

kafka命令行操作 kafka的相关操作命令脚本文件在bin目录下 查看所有的topic kafka-topics.sh --zookeeper hll1:2181 --list 或 kafka-topics.sh --zookeeper 192.168.171.132:2181 --listkafka-topics.sh:topic执行脚本 --zookeeper hll1:2181:需要的…

[carla]把carla世界坐标系 转换为 俯视地图像素坐标系

在下面这篇参考博客中介绍了如何手动获取从carla世界坐标系到俯视地图像素坐标系的旋转平移矩阵.我也是采用了一样的思路和代码,这里把实现的过程以及最后所有地图的变换矩阵记录如下. 参考博客:carla真实世界坐标系与全局俯视地图像素坐标系变换 文章目录代码:1.carla世界坐标…

【表白】html表白代码

目录一.引言二.表白效果展示1.惊喜表白2.烟花表白3.玫瑰花表白4.心形表白5.心加文字6.炫酷的特效一.引言 我们可以用一下好看的网页来表白,下面就有我觉得很有趣的表白代码 下载整套表白文件 二.表白效果展示 1.惊喜表白 2.烟花表白 源码:新建一个文本文…

基于51单片机的温度控制系统数码管显示蜂鸣器报警proteus仿真原理图PCB

功能: 0.本系统采用STC89C52作为单片机 1.系统实时监测并显示当前温度,并通过四位数码管显示 2.超过设定阈值,蜂鸣器将报警,同时控制相应继电器实现降温或者加热 3.系统具备三个功能按键,可更改温度上限和下限 4.采用D…

SpringBoot+Mybatis-Plus+Thymeleaf 实现增删改查+登录/注册

SQL -- student_info create table if not exists student_info ( sid int not null auto_increment comment 学生表主键 primary key, sname varchar(20) not null comment 学生账号登录名、姓名, pwd varchar(32) not null comment 密码, sex varchar(20) not null comment …

AQS源码解析 7.共享模式_CyclicBarrier重复屏障

AQS源码解析 —共享模式_CyclicBarrier重复屏障 简介 CyclicBarrier:循环屏障、循环栅栏,用来进行线程协作,等待线程满足某个计数。构造时设置『计数个数』,每个线程执行到某个需要“同步”的时刻调用 await() 方法进行等待&…

【多目标进化优化】多目标进化群体的分布性

0 前言 \quad\quad进化算法是模拟生物自然进化的人工方法,与大自然生态环境一样,进化的物种也需要平衡发展。因此,设计者必须制定合适的生存规则来维持种群的多样性和分布性。在多目标进化算法中,对于某些问题,Pareto最…

微机-------可编程并行接口8255A

目录 8255A的内部结构8255A控制信息和传输动作的对应关系⭐8255A的控制字一、方式选择控制字①方式0(基本输入输出工作方式)二、端口C置1/置0控制字8255A的工作方式②方式1(选通的输入输出工作方式)③方式2(双向传输方式)⭐⭐8255的编程及应用8255A的内部结构 ①数据总线…

Steam项目推进(二)—— 在项目中使用FairyGUI

一、遇到的问题 昨天把代码大致清理了一遍之后,发现代码中存在很大的一个问题是数据和表现耦合在一起了,如下: using UnityEngine; using UnityEngine.UI;public enum CardStateType {InDeck, InHand, InBattle, InSave, InAbandon }//卡牌…

Cisco简单配置(十八)—OSPF

开放式最短路径优先(Open Shortest Path First,OSPF)是广泛使用的一种动态路由协议,它属于链路状态路由协议,具有路由变化收敛速度快、无路由环路、支持变长子网掩码(VLSM)和汇总、层次区域划分…

设计模式-组合模式(决策树)

一、只如初见 组合模式也许大家第一联想到的就是把两个模块组合起来使用,其实好像是这样也其实不是这样,废话不多说,学习一件新的事物总要先了解一下他的概念,老规矩先上概念(摘自百度百科): 组…

【活动预告】金融大数据治理实践分享(12/03)

原创 DAMA数据管理 # 本期主题 金融大数据治理实践分享 数字化时代,数据的价值受到越来越多的关注,有人将其比作黄金,也有人将其比作石油,成为组织中的最重要资产之一。针对数据这种有特殊属性的资产,也存在着采集…