java的动态代理底层解析

1.说明

代理模式的解释:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。

2.类型:

CGLib动态代理和JDK动态代理

3.使用介绍

(1)CGLib动态代理的使用

使用示例:

1、针对代理类的示例

2 、针对代理接口的示例

(2)JDK动态代理的使用

4.底层分析(通过JVM添加参数-Dcglib.debugLocation=D:\IdeaProjects\cglib\cglib\target\classes【这个便是代理对象的存储路径】)

代理类的class类(依据文件TestObject$$EnhancerByCGLIB$$783a36a0.class)

(1)代码展示

(2)调用流程说明

当代理对象被调用的时候【假设为test()方法】

CGLIB$CALLBACK_0该属性一开始是没有值的(因为初始化过程没有赋值的步骤),而获取值得步骤在于 CGLIB$BIND_CALLBACKS(this);这一步。

这里面var1明显是指类本身,故CGLIB$BOUND会发现是布尔值类型,默认是false。而CGLIB$THREAD_CALLBACKS在静态代码块中被赋予了ThreadLocal,所以是打算从当前线程的ThreadLocal中获取。而CGLIB$STATIC_CALLBACKS类属性值中存放拦截方法数组的地方。然后返回数组的第一个元素过去。(1.这里有个问题ThreadLocal是什么时候被赋值的?)

(3)问题汇总

1.这里有个问题ThreadLocal是什么时候被赋值的?

是在 CGLIB$SET_THREAD_CALLBACKS 这个方法中被赋值的,CGLIB$SET_THREAD_CALLBACKS这个方法又是在newInstance方法【生成代理对象的方法】中被执行。

2 .test()⽅法内会去调⽤所设置的Callbacks中的intercept(),相当于执⾏增强逻辑,如果没有Callbacks,则会执⾏super.test(),那么我们⾃然能想到,如果不设置Callbacks,那是不是就能正常执⾏呢?(是不能正常执行的)

*

+ 情况1,enhancer.setCallback(null);

异常出现在:createHelper()方法#preValidate()#CallbackInfo.determineTypes(callbacks, false);

会报java.lang.IllegalStateException: Callback is null

*

+ 情况2,不设置enhancer.setCallback

createHelper()方法#preValidate()#CallbackInfo.determineTypes(callbacks, false);

会报java.lang.NullPointerException

(4)分析说明

5.JDK动态代理源码分析(还未写全,待续)

(1)Proxy.newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

6.CGLib源码分析

(1)Enhancer.create()

(2)Enhancer.createHelper()

(3)AbstractClassGenerator.create(Object key)

(4)Enhancer.firstInstance((Class) obj) 与 Enhancer.createUsingReflection(type)

(5)ClassLoaderData.get(this, getUseCache())

7.MethodProxy源码分析

代码展示

代码说明

在使用过程,我们常常遇到methodProxy上的方法使用问题,然而根本不知道为什么会这样。(虽然也不怎么会这样用)

进行分析

(1)MethodProxy是什么时候创建出来的?

从上面的字节码文件可以看到是在静态方法CGLIB$STATICHOOK1()中生成的。

源代码为(MethodProxy类#create方法)

(2)MethodProxy的invoke 方法与invokeSuper方法的区别?

先上代码:

1.说白了,这个两个方法本身是根据不同的索引文件去找对应的方法,然后用传入对象,调用返回的方法。

2.这里面涉及了另外的两个字节码文件(便是上面存储路径下的):

TestObject$$EnhancerByCGLIB$$783a36a0$$FastClassByCGLIB$$626f6578.class(这里面是代理类的方法索引)

TestObject$$FastClassByCGLIB$$a3bbba2f.class (这里面是目标类的方法索引)

(3)FastClassInfo的生成过程

TestObject$$EnhancerByCGLIB$$783a36a0$$FastClassByCGLIB$$626f6578.class代码展示(已经进行了部分删减,可以尝试自己去调试生产厂)

8.拓展内容

ASM技术

引入包类

代码示例

Javassist技术

引入包类

代码示例

Original: https://www.cnblogs.com/chafry/p/16709585.html
Author: 忧愁的chafry
Title: java的动态代理底层解析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/620418/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Ubuntu下安装多个JDK,并设置其中一个为默认JDK

    由于使用需要,要在机器上同时安装OpenJDK 8和11,并将8设置为默认JDK 首先安装OpenJDK sudo apt-get install openjdk-8-jdk su…

    Java 2023年6月14日
    077
  • springboot @Value 获取计算机中绝对路径文件的内容

    默认情况下使用 @Value("aaa.txt") private Resource txtResource; 这样获取到的是项目classpath 下的 aa…

    Java 2023年6月16日
    054
  • 这个简单的小功能,半年为我们产研团队省下213个小时

    大多数人对产研同学的认知都是每天做着高大上的活儿。 我们以为的产研团队是: 研发负责人:今年最新的技术架构是什么、我的团队适合吗? 开发同学:010001,一顿代码猛如虎 测试同学…

    Java 2023年6月8日
    084
  • 我入职腾讯啦

    蚂蚁金服上市的消息我想已经席卷了大家的朋友圈了,我也第一时间慰问了我所有蚂蚁的朋友,有期权的小伙伴都在估算自己变现后数字了,确实有很多老阿里人有财富自由的机会了,也有P7以下没期权…

    Java 2023年6月9日
    059
  • 如何自动化你的Excel导入导出(Java)?

    如遇图片无法显示,请前往掘金查看原文 GitHub | 中文 | English | 博客 为什么使用AutoExcel? Excel导入导出在软件开发中非常常见,只要你接触过开发…

    Java 2023年5月29日
    089
  • Spring Cloud Stream 简介

    一、概述 Spring Cloud Stream 是一个建立在 Spring Boot 和 Spring Integration 之上的框架,有助于创建事件驱动或消息驱动的微服务。…

    Java 2023年5月30日
    069
  • 线程池使用

    线程池 1.工具类实现 undefined 线程池监控: long activeCount = ((ThreadPoolExecutor)instance).getActiveCo…

    Java 2023年6月9日
    077
  • Java SimpleDateFormat[转]

    [补充] [转] http://stackoverflow.com/questions/2603638/why-cant-this-simpledateformat-parse-t…

    Java 2023年5月29日
    099
  • MyBatis架构分析

    我们都知道 Mybatis是一个非常小巧灵活的ORM框架,深受国内广大开发者的喜爱,我们知道它的出现某种程度是为了消除所有的JDBC代码和参数的手工设置以及结果集的封装问题;基于这…

    Java 2023年6月5日
    073
  • JS 模块化- 05 ES Module & 4 大规范总结

    1 ES Module 规范 ES Module 是目前使用较多的模块化规范,在 Vue、React 中大量使用,大家应该非常熟悉。TypeScript 中的模块化与 ES 类似。…

    Java 2023年6月16日
    070
  • nginx重新整理——————http请求的11个阶段中的find_config[十三]

    前言 简单介绍一下find_config 与 preaccess 阶段。 正文 find_config 很大一部分工作是进行location的匹配。 来一张图看下location指…

    Java 2023年5月30日
    073
  • 解决List遍历删除元素提示ConcurrentModificationException

    解决List遍历删除元素提示ConcurrentModificationException JDK1.8提供新的API ===> removeIf @Test public …

    Java 2023年6月5日
    081
  • 面试题:海量数据处理利器-布隆过滤器

    概念 原理 布隆过滤器的使用场景 简单模拟布隆过滤器 Guava布隆过滤器 Redis布隆过滤器 布谷鸟过滤器 作者:小牛呼噜噜 | https://xiaoniuhululu.c…

    Java 2023年6月15日
    0110
  • logback的使用

    一、logback的介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch。 常用处理java的日志组件:slf4…

    Java 2023年6月5日
    065
  • java高级

    包装类 java的数据类型 基本类型 byte,short,char,int,long,float,double,boolean 引用和值都是存储在栈内存中 基本数据类型是没有方法…

    Java 2023年6月7日
    065
  • ARM Java 移植

    arm Java下载 https://www.oracle.com/java/technologies/javaseembedded8u211-downloads.html 官方移…

    Java 2023年5月29日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球