修改对象的行为和值(代理)

文章目录

  • 前言
  • 一、复制一个对象
  • 二、代理对象
      • 重点来了
  • 总结


前言

最近遇到一个需求,需要在某个位置,统一处理对象的一些属性值:
方案有两种:

  1. 直接复制一份,将属性覆盖后,返回一个新对象
  2. 搞一个代理类,代理这个对象,修改对象的原有行为和值,从而达到修改属性值的目的

一、复制一个对象

这里有现成的hutool 方法,当然不用自己造轮子了,废话不多说,直接上代码:

这里有个类,我设置了id为12 ,我想将id属性值修改为2

public class MainTet {
   public static void main(String[] args) {

       Menu menu = new Menu();
       menu.setMenuCode("12");
       menu.setId(12);

       Map<String, Object> overrideProps = new HashMap<>();
       overrideProps.put("id", 2);

       Menu menu1 = overrideField(menu,overrideProps);
       System.out.println(JSONUtil.toJsonStr(menu1));
       System.out.println(JSONUtil.toJsonStr(menu));

   }
	private static <T> T overrideField(T menu,Map<String, Object> overrideProps) {
       Object object = BeanUtil.copyProperties(menu, menu.getClass());
       for (Map.Entry<String, Object> entry : overrideProps.entrySet()) {
           BeanUtil.setFieldValue(object, entry.getKey(), entry.getValue());
       }
       return (T) object;
   }
}
    

新建一个类的结果
可以看到,返回了新对象,然后值已经被修改,原值仍然是12;

二、代理对象

这个就不一般了,它不是新建了对象,而是创建了一个代理类,类似于spring中的代理对象,然后它不修改之前对象的属性,而是增强
大致思路:

  1. 创建代理对象
  2. 拦截方法,拦截后执行代理方法,而非原方法
public class MainTet {
   public static void main(String[] args) {

       Menu menu = new Menu();
       menu.setMenuCode("12");
       menu.setId(12);

       Map<String, Object> overrideProps = new HashMap<>();
       overrideProps.put("id", 2);

		Menu proxy = getProxy(menu,overrideProps);
        System.out.println(proxy.getId());
   }
   
   private static <T> T getProxy(T menu, Map<String, Object> overrideProps) {

        // 创建代理对象
        ProxyFactory proxyFactory = new ProxyFactory(menu);
        proxyFactory.setProxyTargetClass(Boolean.TRUE);

        Map<String, Object> overrideMap = new HashMap<>();

        // 设置代理对象的代理方法
        // 例如 key为id 那么 overrideMap 中的key为getId 和 isid
        overrideProps.forEach((k, v) -> {
            String methodName = "get" + k.substring(0, 1).toUpperCase() + k.substring(1);
            overrideMap.put(methodName, v);
            methodName = "is" + k.substring(0, 1).toUpperCase() + k.substring(1);
            overrideMap.put(methodName, v);
        });

        // 利用方法拦截器拦截调用方法,执行代理方法
        proxyFactory.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                String methodName = invocation.getMethod().getName();
                if (overrideMap.containsKey(methodName)) {
	                // 直接返回覆盖值,不执行原方法
                    return overrideMap.get(methodName);
                }
                // 执行原方法
                return invocation.proceed();
            }
        });
        return (T) proxyFactory.getProxy();
    }
}

打印结果

也被更为了2

重点来了

  • 我在Menu对的getId() 方法中打了断点,但是debug运行过程中,并不会到此处断点
    方法断点

因为,代理后,根本不会执行真正的getId 方法,而是在 MethodInterceptor的 invoke 中,根据判断,直接返回覆盖值


总结

第二种方式比较高大上,相当于手动创建了代理对象,并修改了对象的原有属性和行为!

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

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

相关文章

告别2023,无论何年我都是最幸福的程序员。

序 2023年注定是不平凡的一年&#xff0c;有太多的意外&#xff0c;无论是工作还是家庭。唯一不变的是坚持&#xff0c;岁月的静好&#xff0c;离不开同事们的负重前行&#xff0c;作为一个程序员来说&#xff0c;我是幸运的&#xff0c;也是最幸福的。生活的漫漫长路&#xf…

Node.js基础知识点(二)

一、Node环境安装&#xff08;Windows&#xff09; 1.下载对应的node.js版本:https://nodejs.org/en/download/ 2.下载完成后&#xff0c;双击安装包&#xff0c;开始安装node.js 3.勾选复选框&#xff0c;点击【Next】按钮 4.修改好目录后&#xff0c;点击【Next】按钮 5.此处…

调整几行代码,接口吞吐提升 10 倍,性能调优妙啊!

景 分析过程 总结 背景 公司的一个ToB系统,因为客户使用的也不多,没啥并发要求,就一直没有经过压测。这两天来了一个“大客户”,对并发量提出了要求:核心接口与几个重点使用场景单节点吞吐量要满足最低500/s的要求。 当时一想,500/s吞吐量还不简单。Tomcat按照100个线程…

扫码看文档的方法有哪些?文档生成二维码在线教程

现在经常会看到很多企业的宣传栏都会通过二维码来做通知或者信息的发布与展示&#xff0c;二维码中的常见内容大多是文件内容&#xff0c;比如常见的有word、excel、pdf等类型。那么这种用来展示文件内容的二维码制作的方法是什么样的呢&#xff1f;其实制作文件二维码的方法是…

TS学习笔记一:认识TS及环境准备

本次学习笔记是具有一定js基础的情况下从头开始学习ts相关内容。 视频信息 TS学习笔记一&#xff1a;认识TS及环境准备 B站视频 TS学习笔记一&#xff1a;认识TS及环境准备 西瓜视频 https://www.ixigua.com/7320049274006274560 1.1.目的 通过本次学习&#xff0c;学习并…

【激活函数】SELU 激活函数

1、介绍 SELU (Scaled Exponential Linear Unit) SELU是对ELU激活函数的改进&#xff0c;通过引入自动标准化机制&#xff0c;使得神经网络的隐藏层在训练过程中可以自动地保持输出的均值和方差接近于1。 # 定义 SELU 激活函数 def selu(x, alpha1.67326, lambda_1.0507):retu…

深圳易图讯实景三维数字孪生系统 实景三维电子沙盘

深圳易图讯实景三维数字孪生系统是一款基于三维地理空间的数字孪生系统&#xff0c;首先&#xff0c;该系统集成了多维度地理空间数据&#xff0c;可以将各类数据与应用需求进行充分整合&#xff0c;实现数据跨界融合、场景全角度可视等功能。其次&#xff0c;该系统具备智能化…

计算机毕业设计----ssm大学生兼职论坛

项目介绍 该项目是一个大学生校园兼职平台&#xff0c;分为前台和后台功能&#xff0c;主要用户有三种角色&#xff1a;分别是商家、学生、管理员。商家可以发布兼职信息&#xff0c;发布后&#xff0c;管理员进入后台确认信息是否有效&#xff0c;并且审核该兼职信息。学生登…

【ARM 嵌入式 编译系列 7.2 -- GCC 链接脚本中 DEFINED 函数与 “AT>“ 符号详细介绍】

文章目录 GCC 链接脚本中 DEFINED 函数DEFINED() 函数> (放置在哪个区域)AT> (加载地址) (填充字节) 在链接脚本中&#xff0c;组合示例 GCC 链接脚本中 DEFINED 函数 在 ARM GCC 链接脚本&#xff08;.ld 文件&#xff09;中&#xff0c;DEFINED() 是一种内置函数&…

Verifiable Credentials可验证证书 2023 终极指南

1. 引言 Dock公司为去中心化数字身份领域的先驱者&#xff0c;其自2017年以来&#xff0c;已知专注于构建前沿的可验证证书&#xff08;Verifiable Credentials&#xff09;技术。本文将阐述何为电子证书、电子证书工作原理、以及其对组合和个人的重要性。 伪造实物证书和数字…

Excel中快速隐藏中间四位手机号或者身份证号等

注意&#xff1a;以下方式必须再新增一列&#xff0c;配合旧的一列用来对比操作&#xff0c;即根据旧的一列的数据源&#xff0c;通过新的一列的操作逻辑来生成新的隐藏数据 1、快捷方式是使用CtrlE 新建一列&#xff1a;手动输入第一个手机号隐藏后的号码&#xff0c;即在N2单…

VS2017 搭建opencv工程

VS2017 搭建opencv工程 opencv在处理图像方面具有很强的能力&#xff0c;在使用opencv之前先需要造好轮子。 1、opencv 官网 &#xff0c;下载对应的资源文件包。 根据自身选择。下载包之后&#xff0c;解压。分为build和sources source目录下分别存放&#xff1a; modules: …

C#中的值和引用笔记

文章目录 1. 简单介绍2. 如何判断值类型和引用类型3. 语句块4. 变量的生命周期5. 结构体中的值和引用6. 数组中的存储规则7. 结构体继承接口 1. 简单介绍 2. 如何判断值类型和引用类型 在代码中直接转到内部F12 如string类型 值类型int 3. 语句块 4. 变量的生命周期 5. 结构…

OpenHarmony如何隐藏系统状态栏、导航栏

前言 OpenHarmony源码版本&#xff1a;4.0release 开发板&#xff1a;DAYU / rk3568 一、通过setWindowSystemBarEnable方法设置 当我们应用的Alility继承的是UIAbility时&#xff0c;可以onWindowStageCreate(windowStage: window.WindowStage)方法中实现如下操作&#xf…

国科大图像处理2024速通期末——汇总2017-2019、2023回忆

国科大2023.12.28图像处理0854期末重点 图像处理 王伟强 作业 课件 资料 一、填空 一个阴极射线管它的输入与输出满足 s r 2 sr^{2} sr2&#xff0c;这将使得显示系统产生比希望的效果更暗的图像&#xff0c;此时伽马校正通常在信号进入显示器前被进行预处理&#xff0c;令p…

【C++】STL 算法 ③ ( 函数对象中存储状态 | 函数对象作为参数传递时值传递问题 | for_each 算法的 函数对象 参数是值传递 )

文章目录 一、函数对象中存储状态1、函数对象中存储状态简介2、示例分析 二、函数对象作为参数传递时值传递问题1、for_each 算法的 函数对象 参数是值传递2、代码示例 - for_each 函数的 函数对象 参数在外部不保留状态3、代码示例 - for_each 函数的 函数对象 返回值 一、函数…

Scikit-Learn线性回归(四)

Scikit-Learn线性回归四:梯度下降 1、梯度下降1.1、梯度下降概述1.2、梯度下降及原理1.3、梯度下降的实现2、梯度下降法求解线性回归的最优解2.1、梯度下降法求解的原理2.2、梯度下降法求解线性回归的最优解2.3、梯度下降法求解线性回归案例(波士顿房价预测)3、Scikit-Learn…

女性需要了解的健康知识

女性需要了解的健康知识 一&#xff1a;脸部 羊大师发现&#xff0c;你的面容不断透露出你的生活态度&#xff0c;可以从一个女人的脸上看出她过得好不好。从脸色是苍白无华还是红润可见一斑&#xff1b;从是否素颜自然还是妆容精致&#xff0c;这一切都显露在他人面前。因此&…

vue接入海康4G版摄像头通过萤石云平台推送视频流教程

需求 最近需要接入海康视频摄像头&#xff0c;然后把视频的画面接入到自己的网站系统中。以前对接过rtsp固定IP的显示视频&#xff0c;这次的不一样&#xff0c;没有了固定IP。海康的解决办法是&#xff0c;摄像头通过配置服务器到萤石云平台&#xff0c;然后购买企业版账号和…

【开源】基于JAVA语言的智能教学资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程档案表3.2.2 课程资源表3.2.3 课程作业表3.2.4 课程评价表 四、系统展示五、核心代…