如何实现动态代理(俩种方式)

news2024/9/28 13:18:03

文章目录

  • 基于接口的动态代理:
  • 基于类的动态代理:

基于接口的动态代理:

通过Java的反射机制来动态创建代理对象,代理对象实现了一个或多个接口。

Java提供了java.lang.reflect包中的Proxy类和InvocationHandler接口来实现基于接口的动态代理。通过Proxy.newProxyInstance()方法,你可以传入一个类加载器、一组接口和一个InvocationHandler对象来创建代理对象。

示例背景:
小张想办一场婚礼,但是自己不懂婚礼该如何举办,所以找到婚介所来帮你做这件事情,

  1. 创建一个Mary接口
public interface Mary {
    void getMarry();
}
  1. 创建一个Person类
public class Person implements Mary{
    String name;

    public Person(String name) {
        this.name = name;
    }
    @Override
    public void getMarry() {
        System.out.println(name + "参加婚礼");
    }
}
  1. 创建一个代理DatingAgencies类
public class DatingAgencies implements InvocationHandler {
    private Object targetObj;

    public DatingAgencies(Object targetObj) {
        this.targetObj = targetObj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("婚介所:我来帮你把一切都准备好");
        Object invoke = method.invoke(targetObj, args);
        System.out.println("婚介所:我来帮你把一切都收拾好");
        return invoke;
    }
}
  1. 编写一个主方法进行测试
public class Main {
    public static void main(String[] args) {
        Person person = new Person("小张");
        DatingAgencies datingAgencies = new DatingAgencies(person);
        Mary meWant = (Mary) Proxy.newProxyInstance(person.getClass().getClassLoader(),
                person.getClass().getInterfaces()
                , datingAgencies);
        meWant.getMarry();
    }
}

运行结果如下:
在这里插入图片描述
从上实验中,我们就能知道,小张把一切的事情都交给婚介所来做,自己只需要参加婚礼就可以了,婚介所相当于一个代理对象,而小张相当于一个目标对象

基于类的动态代理:

基于类的动态代理是通过创建一个动态生成的子类来实现代理。Java提供了java.lang.reflect包中的Proxy类和InvocationHandler接口,以及cglib库来实现基于类的动态代理。基于类的动态代理不要求目标对象实现特定的接口,而是直接创建目标对象的子类,并重写其中的方法来实现代理逻辑。

注意:实现本实验的动态代理需要用到asm-4.1.jar , 以及 cglib-3.1.jar 这俩个jar包

同上示例相同讲解:

  1. 创建一个Person对象
public class Person{
    String name;

    public void getMarry() {
        System.out.println(name + "参加婚礼");
    }
}
  1. 创建一个DatingAgencies代理类
public class DatingAgencies implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("婚介所:我来帮你把一切都准备好");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("婚介所:我来帮你把一切都收拾好");
        return result;
    }
}
  1. 编写测试类进行测试
public class Main {
    public static void main(String[] args) {
        // 创建Enhancer对象,用于生成代理对象
        Enhancer enhancer = new Enhancer();
        // 设置目标类为RealObject
        enhancer.setSuperclass(Person.class);
        // 设置回调对象为DatingAgencies
        enhancer.setCallback(new DatingAgencies());
        // 生成代理对象
        Person person = (Person) enhancer.create();
        person.name = "小张";
        // 调用代理对象的方法
        person.getMarry();
    }
}

在这个示例中,我们首先定义了一个Person类,它是我们想要代理的目标类。然后,我们创建了一个DatingAgencies类,它实现了cglib库中的MethodInterceptor接口,用于定义代理逻辑。在Main类中,我们使用Enhancer类来设置目标类和回调对象,并生成代理对象。当调用代理对象的方法时,DatingAgencies中的intercept方法会被调用,从而在目标方法执行前后添加额外的逻辑。

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

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

相关文章

仰暮计划|“他说,他是出生于两个时代的人”

凌保庆老爷爷,1942年10月4日出生,今年82岁,家住在河南省登封市唐庄乡磨沟村。7月28日,我作为仰暮计划小队的一员去拜访了这位老人,听凌爷爷讲述了他的故事。 走进这户人家的时候,凌爷爷正在书房里。虽然家…

Spring Cloud 系列:基于Seata 实现 XA模式

https://seata.io/zh-cn/docs/user/mode/xa https://seata.io/zh-cn/docs/dev/mode/xa-mode XA 规范 是 X/Open 组织定义的分布式事务处理(DTP,Distributed Transaction Processing)标准,XA 规范 描述了全局的TM与局部的RM之间的…

【深度学习】线性回归模型与梯度下降法

线性回归模型与梯度下降法 线性回归模型与枚举法 线性回归模型定义: w:权重b:偏置#mermaid-svg-ZAxF27Mw5dXNQgw2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ZAxF27Mw5dXNQgw2 .error-icon{fill:#552222;}…

大数据开发之Spark(完整版)

第 1 章:Spark概述 1.1 什么是spark 回顾:hadoop主要解决,海量数据的存储和海量数据的分析计算。 spark是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。 1.2 hadoop与spark历史 hadoop的yarn框架比spark框架诞生的晚&#xff…

JRT的无源码发布

之前介绍过JRT最大的特点就是业务脚本化。老javaer就会说你业务代码都在发布环境放着,那怎么代码保密,在发布环境别人随便改了启不是不安全,或者一些代码我就是不想让人看源码呢。 其实JRT的业务脚本化只是特性,不是代表就必须要…

【域名解析】如何将域名指向对应服务器IP

目录 🌷一、域名解析基本概念 🌼1. 定义 🌼2. 域名解析类型 🌷二、域名解析服务器IP地址 🌼1. 操作步骤 🌼2. 验证 🌷一、域名解析基础知识 🌼1. 基本概念 定义: …

【操作系统】实验八 proc文件系统

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

破解不了WIFI?也许你应该试试社工...

以下案例为虚拟环境,请勿模仿 做什么? 由于工作出差在该某某企业出差,手机和电脑都没办法用流量…流量包1G1块…太贵了…我勒个豆啊…发现WIFI密码难以破解(小kali上过了)。 出去逛逛吧…发现楼道有海康威视摄像头,学过交换机的一般都看得出来这个摄像…

jquery多选框

使用hbuilder <!DOCTYPE html> <html><head><meta charset"GBK"><title></title></head><body><table id"myTable"> <tr> <td>黄1</td> </tr> <tr> <td>…

C语言通过IXMLHttpRequest以get或post方式发送http请求获取服务器文本或xml数据

做过网页设计的人应该都知道ajax。 Ajax即Asynchronous Javascript And XML&#xff08;异步的JavaScript和XML&#xff09;。使用Ajax的最大优点&#xff0c;就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作&#xff0c;并避免了在网络上发…

计算机网络——网络层(1)

计算机网络——网络层(1&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 网络层&#xff1a;数据平面网络层概述核心功能协议总结 路由器工作原理路由器的工作步骤总结 网际协议IPv4主要特点不足IPv6主要特点现状 通用转发和SDN通用转发SDN&#xff08;软件…

《WebKit技术内幕》学习之十三(3):移动WebKit

3 其他机制 3.1 新渲染机制 为了移动领域更好的用户体验&#xff0c;渲染机制所做的改进主要是提升渲染性能来增加响应的速度&#xff0c;甚至不惜牺牲一些跟规范定义的行为不一致的地方。在这一小节中主要介绍三个方面的技术&#xff0c;其一是Tiled Backing Store&#x…

【LLM】FuseLLM:大模型融合trick-知识融合LLMs

前言 传统的模型融合方法分为集成的方法和权重合并的方法&#xff0c;这两种方法在以往的NLP的比赛中非常常见&#xff0c;是一种提分手段。然而&#xff0c;上述两种方法都需要预训练或者微调相应的模型。在大模型场景下&#xff0c;对每个源模型都进行初始化成本太高&#x…

是用原生js创建红包雨效果

需求: 创建红包雨 答案: // 红包雨代码 开始 // 添加遮罩层 const addOverlay () > {const overlay document.createElement(div);overlay.className overlay;overlay.style.position fixed;overlay.style.top 0;overlay.style.left 0;overlay.style.width 100%;o…

华为机考入门python3--(0)测试题1-句子平均重量

分类&#xff1a;字符串 知识点&#xff1a; 获取输入 input().strip().split(" ") 拼接列表 " ".join(list) 输出指定位数的浮点数 print("%.2f" % value) len() 函数对于很多内置的数据类型都适用&#xff0c;它返回对象的元素个数或长度。…

Qt6入门教程 11:父子对象关系

在上一篇中的纯手写部分&#xff0c;不管是创建菜单、工具栏还是状态栏&#xff0c;我们new完之后都未显式的调用delete进行销毁&#xff0c;这样难道不会有内存泄漏么&#xff1f; QMenuBar *menuBar new QMenuBar(this); QToolBar *toolBar new QToolBar(this); QStatusBa…

yolov8上使用gpu教程

yolov8上使用gpu教程 安装Cuda和Cudnnyolov8上使用gpu 安装Cuda和Cudnn 1.查看支持的cuda版本&#xff0c;并去官网下载。 nvidia-smi2.网址&#xff1a;https://developer.nvidia.com/cuda-toolkit-archive 3.安装细节 安装的前提基础是&#xff0c;有vs的C环境。我电脑有…

GBASE南大通用Connection 构造函数

GBASE南大通用分享  重载列表 1) 初始化一个新的 GBaseConnection 类实例。 GBaseConnection() 2) 当给定连接字符串的时候初始化一个新的 GBaseConnection 类实例。 GBaseConnection(string)  注释 当创建一个新的 GBaseConnection 实例的时候&#xff0c;其属性设…

DataStream API(源算子)

目录 源算子 1&#xff0c;从集合中读取数据 2&#xff0c;从文件读取数据 3&#xff0c;从 Socket 读取数据 4&#xff0c;从 Kafka 读取数据 5&#xff0c;自定义源算子 6&#xff0c;Flink 支持的数据类型 6.1 Flink 支持多种数据类型&#xff0c;包括但不限于&…

动态SQL:MyBatis强大的特性之一

一般来说&#xff0c;一个程序的服务器可以部署多个&#xff0c;但是数据库却只能有一个。这么多服务器&#xff0c;如果每天都要给数据库海量的操作数据&#xff0c;数据库的压力就会非常大。 所以为了减轻数据库的压力&#xff0c;我们可以把一些查询数据库的语句简化&#…