系列三十三、代理(三)动态代理

news2024/9/23 14:10:37

一、概述

        在实际开发过程中,往往我们自己不会去创建代理类,而是通过JDK提供的Proxy类在程序运行时,运用反射机制动态创建而成,这就是所谓的动态代理。 

1.1、动态代理 vs 静态代理

        静态代理需要程序员自己写代理类,动态代理不需要。动态代理虽然不需要程序员自己写代理类了,但是还是需要我们定义对被代理对象直接访问方法的拦截,用于对拦截的方法做增强。动态代理技术在框架中使用的场景很多,例如:MyBatis、Spring、SpringMVC等

二、API

2.1、Proxy

public class Proxy extends Object implements Serializable

提供了用于创建动态代理类和对象的静态方法

2.2、InvocationHandler

三、案例代码

3.1、pom

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
  </dependency>
  <!-- 普通maven项目中使用Sl4j注解 -->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.22</version>
  </dependency>
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version>
  </dependency>
  <dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.10</version>
  </dependency>
</dependencies>

3.2、Star

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/29 23:31
 * @Description: 抽象角色
 */
public interface Star {
    /**
     * 唱歌
     * @param musicName 歌曲名字
     * @return
     */
    String sing(String musicName);
    /**
     * 跳舞
     */
    void dance();
}

3.3、SuperStar

/**
 * @Author : 一叶浮萍归大海
 * @Date: 2023/10/29 23:32
 * @Description: 被代理角色
 */
@Data
public class SuperStar implements Star {

    /**
     * 歌手名字
     */
    private String starName;

    public SuperStar() {
    }

    public SuperStar(String starName) {
        this.starName = starName;
    }

    @Override
    public String sing(String musicName) {
        System.out.println(this.starName + "正在唱:" + musicName);
        return "谢谢!谢谢!";
    }

    @Override
    public void dance() {
        System.out.println(this.starName + "正在优美的跳舞");
    }
}

3.4、MyInvocationHandler

@Slf4j
public class MyInvocationHandler implements InvocationHandler {

    private Object obj;

    public MyInvocationHandler(Object obj) {
        this.obj = obj;
    }

    /**
     * 增强逻辑
     *
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 目标方法执行之前
        log.info("目标方法执行之前执行,目标方法名称:{},入参:{}", method.getName(), Arrays.toString(args));
        // 目标方法执行
        Object result = method.invoke(obj, args);
        // 目标方法执行之后
        log.info("目标方法执行之后执行,result:{},obj:{}",result,obj.getClass());
        return result;
    }
}

3.5、测试

@Slf4j
public class App {
    public static void main(String[] args) {
        m4();
    }

    /**
     * Star动态代理:实现InvocationHandler接口方式
     */
    private static void m4() {
        Star targetObj = new SuperStar("杨超越");
        MyInvocationHandler proxy = new MyInvocationHandler(targetObj);
        Star proxyObj = (Star) Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), proxy);

        String result = proxyObj.sing("奢香夫人");

        System.out.println("result = " + result);

        proxyObj.dance();
    }

    /**
     * Star动态代理:匿名内部类方式
     */
    private static void m3() {
        // target
        SuperStar target = new SuperStar("杨超越");

        // 被代理对象的类加载器
        ClassLoader classLoader = target.getClass().getClassLoader();

        // 被代理对象实现的所有接口
        Class<?>[] interfaces = target.getClass().getInterfaces();

        Star proxyStar = (Star) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            /**
             * invoke方法的执行实际:
             *      代理对象调用方法,就会触发此方法执行
             *
             * invoke方法的参数:
             *      参数1:Object proxy,代理对象,不用!
             *      参数2:Method method,代理对象调用的方法,封装Method对象
             *      参数3:Object[] args,数组里存放的是代理对象调用目标方法传递的数据
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                log.info("方法名称:{},参数:{}", method.getName(), Arrays.asList(args));
                log.info("target Method execute before");

                Object result = method.invoke(target, args);

                log.info("目标方法返回结果:{}",result);

                System.out.println("target Method execute after");

                return result;
            }
        });
        System.out.println("proxyStar = " + proxyStar.getClass());

        String result = proxyStar.sing("奢香夫人");
        System.out.println("result = " + result);
    }

}

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

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

相关文章

软件测试面试百问:如何测试App性能?

APP性能测试几乎是客户端面试必问。 为什么要做App性能测试 如果APP总是出现卡顿或网络延迟的情况&#xff0c;降低了用户的好感&#xff0c;用户可能会抛弃该App&#xff0c;换同类型的其他应用。如果APP的性能较好&#xff0c;用户体验高&#xff0c;使用起来丝滑顺畅&…

干货:传统软文和新媒体软文的区别在哪儿

其实早在古代就有软文的影子&#xff0c;不管是“借问酒家何处有&#xff0c;牧童遥指杏花村”&#xff0c;还是“日啖荔枝三百颗,不辞长作岭南人。”都有软文的影子。今天媒介盒子就来和大家聊聊&#xff0c;传统软文和新媒体软文的区别在哪儿&#xff1f; 一、 渠道不同 在…

UWB智能制造

&#xff08;一&#xff09;无人值守的人、车、物出入监控 &#xff08;二&#xff09;人、车、物授权区域进出监控 &#xff08;三&#xff09;固定资产区域盘点及移动盘点 &#xff08;四&#xff09;人、车、物作业现场网格化管理 &#xff08;五&#xff09;作业现场人车、…

万兆光模块是否能够应对未来网络的需求?

万兆光模块目前已经是数据中心等高性能计算场景中的标配之一&#xff0c;其传输速率可以满足大量的数据传输需求。随着网络的发展&#xff0c;光模块的传输速率也在不断提升。目前一些厂商已经推出了400G和800G光模块&#xff0c;同时更高速率光模块也在加速研发中。可以预见&a…

原型和原型链的理解

记住一句话&#xff1a;万物皆对象 对于原型和原型链&#xff0c;我们要知道一下几个&#xff1a;函数对象&#xff0c;实例对象、原型对象 1&#xff09;函数对象——就是平时称的对象&#xff1b; 2&#xff09;实例对象——new出的对象或者{ }&#xff1b; 3&#xff09;原型…

医疗安全不良事件管理系统源码(PHP+ vue+laravel)

医疗安全不良事件管理系统全套源码 不良事件上报系统源码 不良事件管理系统帮助医院梳理建立不良事件上报与管理的一体化解决方案&#xff0c;包含上报内容、归口科室、上报流程及管理办法。提供面向医院的不良事件全过程管理平台&#xff0c;包含事件上报、事件处理、事件追踪…

线性代数 第一章 行列式

一、概念 不同行不同列元素乘积的代数和&#xff08;共n!项&#xff09; 二、性质 经转置行列式的值不变&#xff0c;即&#xff1b; 某行有公因数k&#xff0c;可把k提到行列式外。特别地&#xff0c;某行元素全为0&#xff0c;则行列式的值为0&#xff1b; 两行互换行列式…

goland setup go env

go env -w设置的变量&#xff0c;在goland中不生效&#xff0c;需要额外配置。 点击goland->preference&#xff0c;在go module里&#xff0c;设置go环境变量即可。

Istio实战(九)-Envoy 流量劫持

前言 Envoy 是一款面向 Service Mesh 的高性能网络代理服务。它与应用程序并行运行,通过以平台无关的方式提供通用功能来抽象网络。当基础架构中的所有服务流量都通过 Envoy 网格时,通过一致的可观测性,很容易地查看问题区域,调整整体性能。 Envoy也是istio的核心组件之一…

JS获取阿里云oss私有图片需要通过SDK加签名访问问题

文章目录 一、问题背景二、了解一些概念1. 防盗链2. 公有和私有两种链接的区别 三、下载SDK的地址四、js的SDK对url加签名实现方法实现示例 五、另外1. 跨域问题 六、文章用到的官方文档链接 一、问题背景 我们项目中平时需求都是上传一张原始图片到阿里云OSS公共空间&#xf…

利用OSG和GLSL实现彩色图转为灰度图

目录 1. 前言 2. 开发环境说明 3. 预备知识 4. 功能实现 4.1. 代码 4.2. 代码说明 5. 附加说明 1. 前言 灰色图片其rgb值是一样的&#xff0c;比如(0.5, 0.5, 0.5)就是一张灰度图。彩色转黑白算法有很多种。因此由彩色转黑白关键就是由彩色的rgb算出灰度gray&#xff0…

7+共病思路。WGCNA+多机器学习+实验简单验证,易操作

今天给同学们分享一篇共病WGCNA多机器学习实验的生信文章“Shared diagnostic genes and potential mechanism between PCOS and recurrent implantation failure revealed by integrated transcriptomic analysis and machine learning”&#xff0c;这篇文章于2023年5月16日发…

数据结构与算法解析(C语言版)--搭建项目环境

本栏目致力于从0开始使用纯C语言将经典算法转换成能够直接上机运行的程序&#xff0c;以项目的形式详细描述数据存储结构、算法实现和程序运行过程。 参考书目如下&#xff1a; 《数据结构C语言版-严蔚敏》 《数据结构算法解析第2版-高一凡》 软件工具&#xff1a; dev-cpp 搭…

调试AOSP源码的官方神器-Android Studio for Platform(ASfP)

文章目录 下载安装启动AOSP导入调试不足 欢迎关注微信公众号ZZH的Android 下载 下载地址平台版 Android Studio 由于该工具在调试源码时需要对AOSP进行编译&#xff0c;所以目前只有Ubuntu版本&#xff0c;后续应该也只会有Ubuntu版本。 Ubuntu环境下显示可下载 Windows系统…

【Redis】认识Redis-特点特性应用场景对比MySQL重要文件及作用

文章目录 认识redisredis的主要特点redis的特性&#xff08;优点&#xff09;redis是单线程模型&#xff0c;为什么效率这么高&#xff0c;访问速度这么快redis应用场景redis不可以做什么MySQL和Redis对比启动RedisRedis客户端Redis重要文件及作用 认识redis redis里面相关的小…

SHCTF2023 山河CTF Reverse Week3 --- ststst easyre WP详解

文章目录 [WEEK3]ststst[WEEK3]easyre [WEEK3]ststst 64 bit 的 ELF 文件 sub_400763点进去看看 mprotect &#xff0c;这个 这一题是SMC TEA的考察&#xff0c;我写过一篇关于 SMC学习网鼎杯jocker 可以使用idapython写脚本自动修复&#xff0c;也可以使用动态调试&#x…

吉他、班卓琴和贝斯吉他降分器:Arobas Music Guitar 8.1.1

Arobas Music Guitar 是一款专业的吉他、班卓琴和贝斯吉他降分器。在熟练的手中&#xff0c;它不仅可以让您创作&#xff0c;还可以编辑、聆听和录制&#xff0c;以及导入和导出乐谱。如果有人感兴趣的话&#xff0c;录音是在八个轨道上进行的&#xff0c;你可以为每个轨道单独…

1.8 网络安全模型

思维导图&#xff1a; 1.8 网络安全模型笔记&#xff1a; 网络安全模型核心概念: 消息在Internet上从发送方传送至接收方&#xff0c;涉及到源地址、目的地址、通信协议&#xff08;如TCP/IP&#xff09;的使用。信息交换的双方需要合作保证交换的可靠性。 安全技术核心组成…

发布一款CAN总线接口的GPS模块

一、模块硬件介绍 GNSS模块&#xff1a;u-blox M9N&#xff0c;支持北斗、GPS、格洛纳斯和伽利略四系统并发处理陶瓷天线&#xff1a;太盟PA025AZ009&#xff0c;支持北斗、GPS、格洛纳斯三系统。根据太盟的回复&#xff0c;25*25*4尺寸的陶瓷天线无法做到完美的四系统兼容&am…

软考系统架构师知识点集锦十:计算机网络、数学与经济管理、知识产权与标准化

一、计算机网络 1.1、考情分析 2.1 TCP/IP协议簇 2.1.1常见协议及功能 网际层是整个TCP/IP体系结构的关键部分,其功能是使主机可以把分组发往任何网络并使分组独立地传向目标。 POP3: 110 端口&#xff0c;邮件收取SMTP: 25 端口&#xff0c;邮件发送FTP: 20数据端口/21控制…