对于JDK动态代理和Cglib动态代理,如何分析和实现?

JDK动态代理和Cglib动态代理都是Java中常用的动态代理实现方式,它们各有特点和应用场景:

  1. JDK动态代理:JDK动态代理是基于接口的代理方式。它使用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口来创建代理对象。在这种方式下,代理类在运行时动态创建,并且必须实现一个或多个接口。使用JDK动态代理时,你需要提供一个实现了InvocationHandler接口的类,这个类的invoke方法将定义代理逻辑。

    实现步骤大致如下:

    • 定义一个接口和该接口的实现类;
    • 创建一个实现了InvocationHandler接口的处理器类;
    • 使用Proxy.newProxyInstance方法动态创建代理对象。
  2. Cglib动态代理:与JDK动态代理不同,Cglib代理不需要接口,它是通过继承方式实现的。Cglib包含了一组底层字节码操作工具,能动态生成新的类。它通过继承目标类并重写其中的方法来实现代理。由于是通过继承实现,因此它不能代理声明为final的类和方法。

    实现步骤大致如下:

    • 创建一个实现了MethodInterceptor接口的类;
    • 使用Cglib的Enhancer类来创建代理对象,指定父类和回调。

在选择使用哪种代理方式时,如果所有目标对象都实现了接口,可以使用JDK动态代理;如果目标对象没有实现接口,或者你需要代理类的所有方法,那么可以考虑使用Cglib代理。

JDK动态代理

如何创建代理对象:使用Proxy类中的newProxyInstance方法

创建代理对象的要求:被代理类至少实现一个接口

newProxyInstance方法的参数

ClassLoader:类加载器,同于加载被代理对象字节码

Class[]:字节码数组---用于让代理对象和被代理对象拥有相同的方法

InvocationHandler:用于提供被增强的代码

/**接口类*/
public interface FindHouse2 {/*** 找房子*/void find1();/*** 找房子*/void find2();/*** 获取名字* @return*/String getName();}/**测试类
*/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class Test {public static void main(String[] args) {//如何动态创建一个代理类对象(接口的代理类对象)//【这里代理的是FindHouse2.class类】FindHouse2 obj = (FindHouse2) (Proxy.newProxyInstance(FindHouse2.class.getClassLoader(),new Class[]{FindHouse2.class},new MyInvocationHandler()));//调用代理类对象的find1()方法obj.find1();//调用代理类对象的find2()方法obj.find2();//调用代理类对象的getName()方法System.out.println(obj.getName());}///方法调用处理器///private static class MyInvocationHandler implements InvocationHandler {//钩子函数//obj.find1()  => 调用方法//在调用方法时,回调这个钩子@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("正在努力找房源...");System.out.println("ing...");System.out.println("找到了xxx的房子");//返回 null   -> 相当于是void//返回 其他值  -> 相当于是对应的值的类型return "哈哈";}}}

 

Cglib动态代理

1. 定义类(无需接口):

public class MyCglibClass {public void doSomething() {System.out.println("Doing something...");}
}

2. 创建MethodInterceptor:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;public class MyMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method");Object result = proxy.invokeSuper(obj, args);System.out.println("After method");return result;}
}

3. 创建代理实例:

public class Demo {public static void main(String[] args) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(MyCglibClass.class);enhancer.setCallback(new MyMethodInterceptor());MyCglibClass proxy = (MyCglibClass) enhancer.create();proxy.doSomething();}
}

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

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

相关文章

go基础-垃圾回收+混合写屏障GC全分析

垃圾回收(Garbage Collection,简称GC)是编程语言中提供的自动的内存管理机制,自动释放不需要的对象,让出存储器资源,无需程序员手动执行。 Golang中的垃圾回收主要应用三色标记法,GC过程和其他用户goroutine可并发运行…

[Tcpdump] 网络抓包工具使用教程

往期回顾 海思 tcpdump 移植开发详解海思 tcpdump 移植开发详解 前言 上一节,我们已经讲解了在海思平台如何基于静态库生成 tcpdump 工具,本节将作为上一节的拓展内容。 一、tcpdump 简介 「 tcpdump 」是一款强大的网络抓包工具,它基于…

Vue学习笔记之生命周期函数

生命周期示意图如下所示: beforeCreate:组件初始化之前触发该事件created:组件初始化完毕触发该事件beforeMount:Vue应用对象挂载DOM结点之前触发该事件mounted:DOM结点挂载成功之后触发该事件beforeUpdate&#xff1a…

【Spring连载】使用Spring Data访问Redis(二)----关于连接工厂

【Spring连载】使用Spring Data访问Redis(二)----关于连接工厂 一、Drivers二、RedisConnection和RedisConnectionFactory三、配置 Lettuce 连接器四、配置 Jedis 连接器 一、Drivers 使用Redis和Spring的首要任务之一是通过IoC容器连接到存储。为此&am…

Springboot 快速集成 ES

1、Springboot 官网给出的版本选择标准 2、选择版本依赖 我的 elasticsearch 服务版本为 7.17.13&#xff0c;所以 springboot 版本我选用 2.7.10 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies<…

【Linux】wait()和waitpid()函数

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;Linux系列专栏&#xff1a;Linux基础 &#x1f525; 给大家…

CRG设计之复位

1. 前言 CRG(Clock and Reset Generation&#xff0c;时钟复位生成模块) 模块扮演着关键角色。这个模块负责为整个系统提供稳定可靠的时钟信号&#xff0c;同时在系统上电或出现故障时生成复位信号&#xff0c;确保各个模块按预期运行。简而言之&#xff0c;CRG模块就像是SoC系…

代码随想录算法训练营第六天 - 哈希表part01

哈希表 笔记&#xff1a; 哈希表能解决什么问题呢&#xff0c;一般哈希表都是用来快速判断一个元素是否出现集合里。当我们遇到了要快速判断一个元素是否出现集合里的时候&#xff0c;就要考虑哈希法。 但是哈希法也是牺牲了空间换取了时间&#xff0c;因为我们要使用额外的数…

网工每日一练(1月30日)

试题1 以太网中的帧属于 &#xff08;B&#xff09; 协议数据单元。 A、物理层 B、数据链路层 C、网络层 D、应用层 试题2 在Linux 系统中&#xff0c;采用 &#xff08;B&#xff09; 命令查看进程输出的信息&#xff0c;得到下图所示的结果。系统启动时最先运行的进程是 &…

黑盒测试用例的具体设计方法(7种)

7种常见的黑盒测设用例设计方法&#xff0c;分别是等价类、边界值、错误猜测法、场景设计法、因果图、判定表、正交排列。 &#xff08;一&#xff09;等价类 1.概念 依据需求将输入&#xff08;特殊情况下会考虑输出&#xff09;划分为若干个等价类&#xff0c;从等价类中选…

项目交付后,PM该如何做复盘总结?

2023已经收尾&#xff0c;那些让我们或焦灼、或紧急、或喜悦、或悲伤的项目也都交付完毕了。为了更好的总结工作成果与反思&#xff0c;各家单位开始一边排练年会舞蹈一边要求员工做出项目交付后复盘方案了&#xff0c;那么&#xff0c;怎样的复盘才会让项目工作更加明确&#…

涂鸦小程序事件系统——小程序间通信

背景信息 一些内聚的、特定的功能模块&#xff0c;可能会被拆分成多个小程序&#xff0c;这些小程序之间需要进行通信、协作&#xff0c;完成数据的传递、状态的同步等。 基础库版本 ≥ 2.9.0 打开其他小程序 小程序可以通过 ty.navigateToMiniProgram 接口打开其他小程序&am…

每日OJ题_算法_前缀和④_力扣238. 除自身以外数组的乘积

目录 力扣238. 除自身以外数组的乘积 解析代码 力扣238. 除自身以外数组的乘积 238. 除自身以外数组的乘积 难度 中等 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数…

1. HarmonyOS 应用开发 TS 准备-1

1. HarmonyOS 应用开发 TS 准备-1 一、TypeScript 是什么 TypeScript 是一种由微软开发的自由和开源的编程语言。 它是 JavaScript 的一个超集&#xff0c;而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。 TypeScript 提供最新的和不断发展的 JavaScript…

美易官方《盘前:道指期货跌0.04% 风险周降临》

盘前&#xff1a;道指期货跌0.04% 风险周降临 随着市场的波动&#xff0c;道指期货在盘前微幅下跌0.04%&#xff0c;投资者们正在迎接一个重要的风险周。这个风险周可能会对市场产生重大影响&#xff0c;因此投资者们需要密切关注。美股股指期货周一盘前涨跌互现&#xff0c;本…

如何在群晖NAS部署office服务实现多人远程协同办公编辑文档

文章目录 本教程解决的问题是&#xff1a;1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制作固定公网访问链接 本教程解决的问题是&#xff1a; 1.Word&#xff0c;PPT&#xff0c;Excel等重要文件存在本地环境&#xff0c;如何在编…

35.【TypeScript 教程】编译选项

TypeScript 编译选项 TypeScript 提供了很多不同功能的编译选项&#xff0c;既可以通过配置 tsconfig.json 文件中的 compilerOptions 属性来实现编译&#xff0c;也可以使用在 tsc 命令后跟随参数这形式&#xff0c;直接编译 .ts 文件。 注意&#xff1a; 当命令行上指定了输…

Web3技术革新:重新定义在线体验

互联网的不断演进塑造了我们的数字生活&#xff0c;而Web3技术的涌现正带来一场前所未有的变革。本文将深入探讨Web3技术的创新&#xff0c;以及它如何重新定义和提升我们的在线体验。 Web3技术的基本概念 Web3是互联网的第三个时代&#xff0c;它将去中心化、区块链、智能合约…

解决import Jetson.GPIO报错“权限错误”

在导入Jetson.GPIO模块时出现权限错误&#xff0c;可能是由于缺少适当的权限或设备权限问题。以下是一些建议&#xff1a; 使用sudo&#xff1a; 尝试使用sudo来运行你的Python脚本或解释器&#xff0c;以获取足够的权限&#xff1a; sudo python your_script.py请注意&#xf…

(一)PySpark3:安装教程及RDD编程(非常详细)

目录 一、pyspark介绍 二、PySpark安装 三、RDD编程 1、创建RDD 2、常用Action操作 ①collect ②take ③takeSample ④first ⑤count ⑥reduce ⑦foreach ⑧countByKey ⑨saveAsTextFile 3、常用Transformation操作 ①map ②filter ③flatMap ④sample ⑤d…