Java中的代理模式

Java中的代理模式

    • 1. 静态代理
    • JDK动态代理
    • CGLib动态代理

1. 静态代理

接口

public interface ICeo {void meeting(String name) throws InterruptedException;
}

目标类

public class Ceo implements ICeo{public void meeting(String name) throws InterruptedException {Thread.sleep(2000);System.out.println("和"+name+"谈成了34亿的项目");}
}

代理类

public class CeoProxy implements ICeo{private Ceo ceo;public CeoProxy(Ceo ceo) {this.ceo = ceo;}@Overridepublic void meeting(String name) throws InterruptedException {System.out.println("秘书登记来访: "+name);StopWatch stopWatch = new StopWatch();stopWatch.start();ceo.meeting(name);stopWatch.stop();double totalTimeMillis = stopWatch.getTotalTimeSeconds();System.out.println("耗时: "+totalTimeMillis);}
}

测试

public class CeoTest {public static void main(String[] args) throws InterruptedException {Ceo ceo = new Ceo();CeoProxy ceoProxy = new CeoProxy(ceo);ceoProxy.meeting("XXX");}
}

JDK动态代理

接口

public interface IDao {void select();
}

目标类

public class UserDao implements IDao{@Overridepublic void select() {try {Thread.sleep(2000);System.out.println("select ----");} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

动态代理类
在这里插入图片描述

public class JdkProxy implements InvocationHandler {private Object target;public JdkProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {StopWatch stopWatch = new StopWatch();System.out.println("前置方法");stopWatch.start();Object obj = method.invoke(target, args);stopWatch.stop();System.out.println("后置方法");System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());return obj;}
}

测试

public class DaoTest {public static void main(String[] args) {UserDao userDao = new UserDao();IDao dao = (IDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new JdkProxy(new UserDao()));dao.select();}
}

总结:

  1. 动态生成代理类
  2. 通过实现接口生成代理类(目标接口必须实现接口)
  3. 代理类是实现接口的方式
  4. 调用目标类使用反射调用
  5. 目标类调用本类方法只会代理一次

CGLib动态代理

在这里插入图片描述

目标类

public class ZlmDao {public void select(){try {Thread.sleep(2000);System.out.println("select ---");} catch (InterruptedException e) {throw new RuntimeException(e);}}
}

代理类

public class CglibProxy implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {StopWatch stopWatch = new StopWatch();stopWatch.start();System.out.println("前置增强");Object result = proxy.invokeSuper(obj, args);stopWatch.stop();System.out.println("后置增强");System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());return result;}
}

测试

public class ZlmDaoTest {public static void main(String[] args) {//实例化增强器Enhancer enhancer = new Enhancer();//设置需要代理的目标类enhancer.setSuperclass(ZlmDao.class);//设置拦截对象回调的实现类enhancer.setCallback(new CglibProxy());//生成代理类ZlmDao zlmDao = (ZlmDao) enhancer.create();zlmDao.select();}
}

总结

  1. 通过ASM第三方框架动态代理
  2. 无需接口(final修饰的类和方法除外)
  3. 代理类通过继承目标类的方式实现代理
  4. 调用目标类,使用子类调用父类的方式直接调用
  5. invokeSuper目标类中调用本类方法会再次代理
  6. incoke目标类中调用本来方法只会调用一次

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

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

相关文章

LearnOpenGL_Day1

文章目录 前期准备下载GLFW下载GLAD 引入库文件生成窗口重要概念——双缓冲 (double buffer)代码实现 学习总结 前期准备 下载GLFW GLFW DOWNLOAD 解压后使用CMake编译至新创建的bulid文件夹下: 下载GLAD 引入库文件 创建好工程&#x…

01 矩阵(力扣)多源广度优先搜索 JAVA

给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。 输入:mat [[0,0,0],[0,1,0],[0,0,0]] 输出:[[0,0,0],[0,1,0],[0,0,0]] 输入…

RWEQ模型教程

详情点击链接:基于“RWEQ”集成技术在土壤风蚀模拟与风蚀模数估算、变化归因分析中的实践应用及SCI论文撰写 前沿 土壤风蚀是一个全球性的环境问题。中国是世界上受土壤风蚀危害最严重的国家之一,土壤风蚀是中国干旱、半干旱及部分湿润地区土地荒漠化的…

03-树1 树的同构(C++)

03-树1 树的同构 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。 现…

在 Amazon EMR 上构建实时数据湖

前言 当公司业务发展遇到瓶颈时,业务分析师以及决策者们总会希望通过交叉分析大量的业务数据和用户行为数据,以解答“为什么利润会下滑?”“为什么库存周转变慢了?”等问题,最终整点“干货”出来从而促进业务发展。 …

Oracle 迁移 Hive 过程中遇到的问题总结

前言 最近一个小伙伴在做从 Oracle 到 Hive 的业务迁移工作,在迁移过程中属实遇到了一些坑,今天就来汇总一下这些坑,避免以后大家其他业务迁移的时候再出现类似的问题,即使出现了也可以拿过来进行对照解决。 问题1:Distinct window functions are not supported: count(…

图文教程:使用 Photoshop、3ds Max 和 After Effects 创建被风暴摧毁的小屋

推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 在 Photoshop 中设置图像 步骤 1 打开 Photoshop。 打开 Photoshop 步骤 2 我已经将小屋的图像导入到Photoshop中以演示 影响。如果您愿意,可以使用其他图像。 图片导入 步骤 3 由于小…

解决 tensorflow 出现的 ImportError: Could not find the DLL(s) ‘msvcp140_1.dll‘. 问题

在安装完tensorflow库后出现 问题详述: ImportError: Could not find the DLL(s) msvcp140_1.dll. TensorFlow requires that these DLLs be installed in a directory that is named in your %PATH% environment variable. You may install these DLLs by downlo…

深入浅出指南:Netty开发【NIO核心组件】

目录 ​Netty开发【NIO核心组件】 1.NIO基础概念 2.NIO核心组件 2.1.Channel&&Buffer简介 2.2.Selector 服务器的多线程版本 服务器的线程池版本 服务器的selector版本 2.3.Buffer 0.ByteBuffer的正确使用流程 1.ByteBuffer类型简介 2.ByteBuffer核心属性说…

记录vue的一些踩坑日记

记录vue的一些踩坑日记 安装Jq npm install jquery --save vue列表跳转到详情页,再返回列表的时候不刷新页面并且保持原位置不变; 解决:使用keepAlive 在需要被缓存的页面的路由中添加:keepAlive: true, {path: /viewExamine,nam…

ubuntu环境安装centos7虚拟机网络主机不可达,ping不通

【NAT模式下解决】1.首先vi /etc/sysconfig/network-scripts/ifcfg-ens33检查ONBOOTyes,保存 2.输入systemctl restart network命令重启网关

flutter:轮播

前言 介绍几个比较有不错的轮播库 swipe_deck 与轮播沾边,但是更多的是一种卡片式的交互式界面设计。它的主要概念是用户可以通过左右滑动手势浏览不同的卡片,每张卡片上都有不同的信息或功能。 Swipe deck通常用于展示图片、产品信息、新闻文章、社…

第四代SHARC® ADSP-21479KBCZ-2A、ADSP-21479BSWZ-2A、ADSP-21479KSWZ-2A高性能DSP(数字信号处理器)

第四代SHARC Processors 现在内置低功耗浮点DSP产品(ADSP-21478和ADSP-21479),可提供改进的性能、基于硬件的滤波器加速器、面向音频与应用的外设以及能够支持单芯片解决方案的新型存储器配置。所有器件都彼此引脚兼容,而且与以往…

Appium+python自动化(二十二)- 控件坐标获取(超详解)

简介 有些小伙伴或者是童鞋可能会好奇会问上一篇中的那个monkey脚本里的坐标点是如何获取的,不是自己随便蒙的猜的,或者是自己用目光或者是尺子量出来的吧,答案当然是:NO。获取控件坐标点的方式这里宏哥给小伙伴们分享和讲解三种方…

2024届IC秋招兆易创新数字IC后端笔试面试题

数字IC后端实现PR阶段设计导入需要哪些文件? 设计导入需要的文件如下图所示。这个必须熟练掌握。只要做过后端训练营项目的,对这个肯定是比较熟悉的。大家还要知道每个input文件的作用是什么。 在吾爱IC后端训练营Cortexa7core项目中,你认为…

Jmeter接口自动化生成测试报告html格式

jmeter自带执行结果查看的插件,但是需要在jmeter工具中才能查看,如果要向领导提交测试结果,不够方便直观。 笔者刚做了这方面的尝试,总结出来分享给大家。 这里需要用到ant来执行测试用例并生成HTML格式测试报告。 一、ant下载安…

整数0 强制转化为指针

整数0强制转化为指针的巧用 在工程中看到以下代码: #define my_container_of(ptr,type,member) \ ((type*)((char *) (ptr) - (unsigned long)(&((type*)0)->member))) ->的优先级高于&。 因此 &((type*)0)->member)的解…

微信小程序quickstartFunctions中云函数的应用

1、在quickstartFunctions文件中新建文件夹和文件 2、index.js 文件书写 const cloud require(wx-server-sdk);cloud.init({env: cloud.DYNAMIC_CURRENT_ENV }); const db cloud.database();// 链表查询试卷和对应的题库 exports.main async (event, context) > {retu…

Terraform学习日记-AWS-EC2

terraform install https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli 这里我们使用 aws-linux-2022 作为执行环境 # sudo yum install -y yum-utils# sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/…

Linux内核中的链表、红黑树和KFIFO

lLinux内核代码中广泛使用了链表、红黑树和KFIFO。 一、 链表 linux内核代码大量使用了链表这种数据结构。链表是在解决数组不能动态扩展这个缺陷而产生的一种数据结构。链表所包含的元素可以动态创建并插入和删除。链表的每个元素都是离散存放的,因此不需要占用连…